python 网站爬虫(四) Scrapy讲解

python 网站爬虫(四) Scrapy讲解

在这里插入图片描述

1、Spider类

Spider 类是 Scrapy 中的主要核心类,它定义了如何爬取某个(或某些)网站。包括爬取的动作(例如是否跟进链接),以及如何从网页的内容中提取结构化数据(爬取item)。spider类是scrapy框架最基础的类,以后配到的许多类,基本上都是继承自它。

Spider 是循环爬取,它的爬取步骤是:
start_requests 方法用 start_urls 中的 URL 初始化 Request ,然后将请求返回结果 Response 作为参数传递给 parse 方法;
parse 是回调函数,它分析传递过来的 Response 的内容,从中提取出 Item 对象、 dict 、 Request 或者包含三者的可迭代数据,将 Request 传递给 Scrapy 继续进行下一轮的循环;
parse 使用 selector 分析 Response 提取向所需的数据。

import scrapy

class DemoSpider(scrapy.Spider):
name = ‘demo’
allowed_domains = [‘https:www.baidu.com’]
start_urls = [‘http://https:www.baidu.com/’]

def parse(self, response):
    pass

运行流程
模板中有一个start_urls参数,这是这个Spider的运行入口,Scrapy会自动的将这个参数中的url发送到Downloader进行下载,并且自动的调用parse方法来处理获得的response。
在parse方法处理response的过程中,我们一般会有可能获取两种对象,一个是最终我们从网页上提取的数据,这种数据我们会将其保存为item对象。另一种是我们获取的接下来要访问的url,这一种我们会将其生成为一个Request对象。这两种获得的对象,我们都会使用yield将其返回出去。Scrapy会自动检测对象的类型,如果是item,则会将其发送到item pipeline进行存储等处理,如果是Request对象,则会再次往Downloader发送进行访问。
每一个Request对象,都会在生成的时候绑定一个回调函数,用来处理这个请求返回的响应结果。

2、xpath

XPath,全称 XML Path Language,即 XML 路径语言。XPath 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历,它使用路径表达式来选取 XML 文档中的节点或节点集。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。

Python 使用 XPath 要先安装 lxml 库

示例:

# python3
# -*- coding: utf-8 -*-
# Filename: xpath_demo.py
"""
练习使用 XPath 提取网页内容

@author: v1coder
"""

from lxml import etree
import requests

headers = {
    
    'User-Agent': ''}

def get_content(url):
    data = requests.get(url, headers=headers).content
    return data

# 简书
def jianshu():
    url = 'https://www.jianshu.com/p/713415f82576'
    data = get_content(url)
    html = etree.HTML(data)
    # p[not(@class)] 为不含 class 属性的 p 节点
    texts = html.xpath('//p[not(@class)]/text()') 
    for text in texts[:-1]:
        print(text)
#jianshu()
# 代码解释:
# //p 为所有 p 元素
# //p[not(@class)] 为所有不含 class 属性的 p 元素
# /text() 为获取当前元素的文本

# 盗版小说网站
def biqukan_com():
    url = 'https://www.biqukan.com/1_1094/5403177.html'
    data = get_content(url)
    html = etree.HTML(data)
    texts = html.xpath('//div[@id="content"]//text()')
    for text in texts:
        print(text)
#biqukan_com()
# 代码解释:
# //div[@id="content"] 为获取包含 id 属性且属性值为 content 的所有 div 元素
# //text() 为获取当前节点及所有后代节点的文本

# 豆瓣电影 TOP250
def top_250():
    url = 'https://movie.douban.com/top250'
    data = get_content(url)
    html = etree.HTML(data)
    # 第一个 span 节点用 span[1]
    texts = html.xpath('//div[@class="hd"]/a/span[1]/text()')
    for text in texts:
        print(text)
#top_250()
# 代码解释:
# /a 为当前节点的直接子节点中的 a 节点
# /span[1] 为直接子节点中的第一个 span 节点

# MZ图1
def mmjpg_com():
    url = 'http://www.mmjpg.com/'
    data = get_content(url)
    html = etree.HTML(data)
    # 获取属性 src 的值,用 attribute::src
    urls = html.xpath('//img[@width="220"]/attribute::src')
    for url in urls:
        print(url)
#mmjpg_com()
# 代码解释:
# /attribute::src' 为获取当前元素的属性 src 的值

# MZ图2
def haopic():
    url = 'http://www.haopic.me/tag/meizitu'
    data = get_content(url)
    html = etree.HTML(data)
    urls = html.xpath('//div[@class="post"]/a/img/@src')
    for url in urls:
        print(url)
#haopic()
# 代码解释:
# //div  获取所有 div 元素
# '//div[@class="post"] 获取包含属性 class 且属性值为 post 的 div 元素
# /a 获取前面节点的直接子节点中的 a 节点
# /img 获取前面节点的直接子节点中的 img 节点
# /attribute::src 获取前面节点的属性 src 的值

# MZ图3
def mzitu():
    url = 'https://www.mzitu.com/'
    data = get_content(url)
    html = etree.HTML(data)
    urls = html.xpath('//img[@width="236"]/attribute::data-original')
    for url in urls:
        print(url)
#mzitu()

3、小例子

下面的代码用来抓取近期腾讯有关python的招聘信息,并将结果保存在job.json文件中。

import scrapy
import json
 
class Job1_Tenxun(scrapy.Spider):
    name = 'job1'
    start_urls = ['https://hr.tencent.com/position.php?keywords=python',]
 
    def parse(self, response):
        res = response.xpath("//tr[@class='even']|//tr[@class='odd']")
        with open('job.json','a',encoding='utf-8') as f:
            for tr in res:
                item = {
    
    
                    'job_name':tr.xpath("./td[1]/a/text()").extract_first(),
                    'job_label':tr.xpath("./td[2]/text()").extract_first(),
                    'num':tr.xpath("./td[3]/text()").extract_first(),
                    'addr':tr.xpath("./td[4]/text()").extract_first(),
                    'time':tr.xpath("./td[5]/text()").extract_first(),
                }
                item = json.dumps(item,ensure_ascii=False)
                f.write(item)
                f.write('\n')
        next_url = response.xpath("//a[@id='next']/@href").extract_first()
        return scrapy.Request('https://hr.tencent.com/%s'%next_url)

猜你喜欢

转载自blog.csdn.net/weixin_47542175/article/details/113102962