scrapy -->CrawlSpider 介绍

scrapy -->CrawlSpider 介绍


1、首先,通过crawl 模板新建爬虫:

scrapy genspider -t crawl lagou www.lagou.com

创建出来的爬虫文件lagou.py:

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

class LagouSpider(CrawlSpider):
    name = ‘lagou‘
    allowed_domains = [‘www.lagou.com‘]
    start_urls = [‘http://www.lagou.com/‘]

    rules = (
        Rule(LinkExtractor(allow=r‘Items/‘), callback=‘parse_item‘, follow=True),
    )

    def parse_item(self, response):
        i = {}
        #i[‘domain_id‘] = response.xpath(‘//input[@id="sid"]/@value‘).extract()
        #i[‘name‘] = response.xpath(‘//div[@id="name"]‘).extract()
        #i[‘description‘] = response.xpath(‘//div[@id="description"]‘).extract()
        return i

lagou.py

2、CrawlSpider 概述及源码分析

1)CrawlSpider概述

 CrawlSpider使用于取全站的话。CrawlSpider基于Spider,但是可以说是为全站爬取而生。CrawlSpiders是Spider的派生类,Spider类的设计原则是只爬取start_url列表中的网页,而CrawlSpider类定义了一些规则(rule)来提供跟进link的方便的机制,从爬取的网页中获取link并继续爬取的工作更适合。

2)CrawlSpider的源码分析 → 方法介绍

①、当我们启动爬虫时,爬取url是从Spider(CrawlSpider继承于Spider)下的 start_requests 函数开始执行的,该方法中会逐个获取lagou.py中 start_urls列表中的url进行request爬取数据并yield出去

# Spider类

    def start_requests(self):
        cls = self.__class__
        if method_is_overridden(cls, Spider, ‘make_requests_from_url‘):
            warnings.warn(
                "Spider.make_requests_from_url method is deprecated; it "
                "won‘t be called in future Scrapy releases. Please "
                "override Spider.start_requests method instead (see %s.%s)." % (
                    cls.__module__, cls.__name__
                ),
            )
            for url in self.start_urls:
                yield self.make_requests_from_url(url)
        else:
            for url in self.start_urls:
                yield Request(url, dont_filter=True)

②、上述每个url爬取完成时会自动调用回调函数:parse函数

parse函数作用:本来由parse函数处理start_urls中的url返回的数据,在CrawlSpider中的parse函数中,是将start_urls中的每个url的返回值response交由_parse_response函数进行处理, 同时设定 parse_start_url 为回调函数(parse_start_url在源码中只返回了空列表,也就是说如果我们要对start_urls中每个url的返回值做处理,重载parse_start_url函数并进行自己代码的编写就可以了。如上述中start_urls中只有一个url:www.lagou.com )↓

③、_parse_response函数作用:

1)如果回调函数是parse_start_url,执行该函数,yield request ; 如果回调函数是rules.callback,执行该函数并yield item转pipelines进行数据处理

2)到rules(规则)中查找follow是否为 True,True表示需要跟进,接着调用_requests_to_follow函数↓

需要注意的是:parse函数是CrawlSpider源码中已经定义好的函数,我们尽量不能重载这函数,避免出错。可以重载的是parse_start_url、process_results 这两个函数

④、_requests_to_follow函数作用:

1)根据用户自定义的rules规则,提取rules中的link链接,将其添加进set集合(避免重复)

2)调用_build_request函数,封装下一层url并进行数据爬取(首页url →下一层url) ,每个url数据爬取完毕后都调用回调函数:_response_downloaded↓

3)调用process_request,即_compile_rules函数下的:rule.process_request = get_method(rule.process_request) ,目的是将rule中的字符串表示的方法映射成真正的方法

⑤、_response_downloaded函数实际调用的是第③步的_parse_response函数:第二层(首层url是首页)每个url爬取完成后回调函数真正执行的地方,如果有第三层url(符号规则),则会继续深度式往第三层、第四层进行数据爬取。

#调用顺序:
  # start_request → 1、 parse → 2、 _parse_response → 3、 parse_start_url → 4、process_results → 5&6、 同时,_parse_response调用_follow_lineks
  # → 7、_build_request → 8、_response_downloaded → 返回执行2、_parse_response ,如此循环# 目的:通过start_request对拉勾网首页页面进行爬取,提取首页页面的所有url,并进行规则匹配。匹配成功则进入该url页面提取我们需要的目标数据

class CrawlSpider(Spider):

    rules = ()

    def __init__(self, *a, **kw):
        super(CrawlSpider, self).__init__(*a, **kw)
        self._compile_rules()

    # 1、Spider中的start_request调用parse回调函数,parse函数直接调用parse_response函数
    def parse(self, response):
        return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)
    # 3、parse的回调函数
    def parse_start_url(self, response):
        return []
    # 4、直接返回response对象
    def process_results(self, response, results):
        return results

    # 7、封装url并进行数据爬取,爬取完成后调用回调函数:_response_downloaded
    def _build_request(self, rule, link):
        r = Request(url=link.url, callback=self._response_downloaded)
        r.meta.update(rule=rule, link_text=link.text)
        return r

    # 6、根据用户自定义的rules规则,提取rules规则中的link链接,将其添加进set集合(避免重复)
    def _requests_to_follow(self, response):
        if not isinstance(response, HtmlResponse):
            return
        seen = set()
        # 抽取rules中LinkExtractor -->allow的规则内容,n为index值,rule为allow中的正则匹配内容,如上面lagou.py中:LinkExtractor(allow=r‘Items/‘)里面的r‘Items/‘
        for n, rule in enumerate(self._rules):
            # 将rule链接(此时rule链接:http://www.lagou.com/Items/),存入set集合(去重),用于匹配我们爬取url,是否符合该链接要求
            links = [lnk for lnk in rule.link_extractor.extract_links(response)
                     if lnk not in seen]
            if links and rule.process_links:
                # 使用用户自定义的process_links处理rules链接,默认不处理
                links = rule.process_links(links)
            for link in links:
                seen.add(link) # 添加到set集合,去重
                # 调用_build_request函数,将
                r = self._build_request(n, link)
                # 对每个Request调用process_request()函数。该函数默认为indentify即不做处理,但本函数是调用了_compile_rules函数,作用看该函数。
                yield rule.process_request(r)

    # 8、执行_build_request 数据爬取完成后的回调函数,实际上是调用第2步中的_parse_response函数,来执行回调函数,然后又返到第3步进行处理,如此循环。
    def _response_downloaded(self, response):
        # 找到当前对应的rules规则
        rule = self._rules[response.meta[‘rule‘]]
        # rule.callback:当前rules规则的callback函数,让_parse_response执行
        return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow)

    # 2、parse、rule下的回调函数的实际执行函数,及是否跟进的判断
    def _parse_response(self, response, callback, cb_kwargs, follow=True):
        if callback:
            # 回调函数有两种:
            # 1)parse函数的回调函数(parse_start_url()),用parse_start_url()处理response对象,返回Request对象
            # 2)如果是rules规则中调用的callback函数,则返回的是Item对象
            cb_res = callback(response, **cb_kwargs) or ()
            cb_res = self.process_results(response, cb_res)
            for requests_or_item in iterate_spider_output(cb_res):
                yield requests_or_item  # yield request:执行的是parse的回调函数。 or yield item:表示该url数据爬取完毕,转到pipelines进行数据处理
        # 5、每个url爬取后,可能会爬取出一些url,通过下面判断是否跟进对这些url进行下一层数据爬取
        if follow and self._follow_links:
            # 需要跟进下一层url的爬取,调用_follow_lineks函数进行处理
            for request_or_item in self._requests_to_follow(response):
                yield request_or_item

    def _compile_rules(self):
        # 将rule中的字符串表示的方法映射成真正的方法
        def get_method(method):
            if callable(method):
                return method
            elif isinstance(method, six.string_types):
                return getattr(self, method, None)

        self._rules = [copy.copy(r) for r in self.rules]
        for rule in self._rules:
            rule.callback = get_method(rule.callback)
            rule.process_links = get_method(rule.process_links)
            rule.process_request = get_method(rule.process_request)

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(CrawlSpider, cls).from_crawler(crawler, *args, **kwargs)
        spider._follow_links = crawler.settings.getbool(
            ‘CRAWLSPIDER_FOLLOW_LINKS‘, True)
        return spider

    def set_crawler(self, crawler):
        super(CrawlSpider, self).set_crawler(crawler)
        self._follow_links = crawler.settings.getbool(‘CRAWLSPIDER_FOLLOW_LINKS‘, True)

图解析:

 



原文地址:https://www.cnblogs.com/Eric15/p/9941197.html

时间: 2024-10-31 10:44:01

scrapy -->CrawlSpider 介绍的相关文章

第三百二十四节,web爬虫,scrapy模块介绍与使用

第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrapy 使用了 Twisted异步网络库来处理网络通讯.

(转)Scrapy安装介绍 windows环境下---

一. Scrapy简介 Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and automated testing

scrapy架构介绍及几种反反爬

一.scrapy架构介绍 1.结构简图: 主要组成部分:Spider,Pipeline,Downloader,Scheduler,Scrapy Engine() 2.结构详细图: 主要步骤: 原文地址:https://www.cnblogs.com/lyq-biu/p/9745974.html

scrapy crawlspider内置方法源码

rules: 有经验的同学都知道它是一个列表,存储的元素时Rule类的实例,其中每一个实例都定义了一种采集站点的行为.如果有多个rule都匹配同一个链接,那么位置下标最小的一个rule将会被使用. __init__: 在源码中可以看到,它主要就是执行了_compile_rules方法,这边暂时不讲. parse: 默认回调方法,同上章一样.不过在这里进行了重写,这里直接调用方法_parse_response,并把parse_start_url方法作为处理response的方法. parse_st

windows下安装Scrapy及scrapy模块介绍

一:安装wheel  wheel介绍 二:安装twisted twisted是由python编写的一款基于事件驱动的网络引擎,使用twisted模块将python的异步请求(异步模型介绍)成为可能且简单易用.Twisted介绍 三:创建scrapy文件 使用命令窗口进入目标目录后 使用命令 scrapy startproject project_name 工程目录结构如图 四:启动爬虫程序 scrapy crawl first --nolog #启动时,不输出日志文件 scrapy crawl

Scrapy - CrawlSpider爬虫

crawlSpider 爬虫 思路: 从response中提取满足某个条件的url地址,发送给引擎,同时能够指定callback函数. 1. 创建项目 scrapy startproject myspiderproject 2. 创建crawlSpider 爬虫 scrapy genspider -t crawl 爬虫名 爬取网站域名 3. 启动爬虫 scrapy crawl 爬虫名 # 会打印日志 scrapy crawl 爬虫名 --nolog crawlSpider 的参数解析:  案例

Scrapy安装介绍

一. Scrapy简介 Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and automated testing

python 2.7 的Scrapy安装介绍

一. Scrapy简介 Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and automated testing

scrapy的介绍、组件、数据流

scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量代码,就能够快速的抓取到数据内容. scrapy使用了twisted异步网络框架来处理网络通讯,来加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求 scrapy的工作流程: 1.首先spiders(爬虫)将需要发送请求的url(requests)经scrapyengine(引擎)交给scheduler(调度器) 2.scheduler(排序,入队)处理后,经scarp