创建文件模板

scrapy genspider -t crawl tencent tencent.com

CrawlSpiders就是为爬取整站孕育而生的,我们以前是分页下一页,然后再yied。这样太麻烦。CrawlSpiders是你只需要写好规则之后。他就会根据你这一页的response得到符合条件的url,然后再进去,再分析。

只需要增加两三行代码就可以替换我们以前的分页逻辑。

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_splash import SplashRequest class TencentSpider(CrawlSpider):
name = 'tencent'
#起始页
start_urls = ['http://lab.scrapyd.cn/page/1']
rules = (
#制定爬取的url规则
Rule(LinkExtractor(allow=r'http://lab.scrapyd.cn/page/'), callback='parse_item', follow=True),
)
#爬取每页的这个数据
def parse_item(self, response):
print(response.xpath('///*[@id="main"]/div[1]/span[1]/text()'))

LinkExtractors

class scrapy.linkextractors.LinkExtractor

Link Extractors 的目的很简单: 提取链接。

每个LinkExtractor有唯一的公共方法是 extract_links(),它接收一个 Response 对象,并返回一个 scrapy.link.Link 对象。

Link Extractors要实例化一次,并且 extract_links 方法会根据不同的 response 调用多次提取链接。

class scrapy.linkextractors.LinkExtractor(
allow = (),
deny = (),
allow_domains = (),
deny_domains = (),
deny_extensions = None,
restrict_xpaths = (),
tags = ('a','area'),
attrs = ('href'),
canonicalize = True,
unique = True,
process_value = None
)

主要参数:

  • allow:满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。

  • deny:与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。

  • allow_domains:会被提取的链接的domains。

  • deny_domains:一定不会被提取链接的domains。

  • restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。

rules

在rules中包含一个或多个Rule对象,每个Rule对爬取网站的动作定义了特定操作。如果多个rule匹配了相同的链接,则根据规则在本集合中被定义的顺序,第一个会被使用。

class scrapy.spiders.Rule(
link_extractor,
callback = None,
cb_kwargs = None,
follow = None,
process_links = None,
process_request = None
)
  • link_extractor:是一个Link Extractor对象,用于定义需要提取的链接。

  • callback: 从link_extractor中每获取到链接时,参数所指定的值作为回调函数,该回调函数接受一个response作为其第一个参数。

    注意:当编写爬虫规则时,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider将会运行失败。

  • follow:是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果callback为None,follow 默认设置为True ,否则默认为False。

  • process_links:指定该spider中哪个的函数将会被调用,从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。

  • process_request:指定该spider中哪个的函数将会被调用, 该规则提取到每个request时都会调用该函数。 (用来过滤request)

源码参考

class CrawlSpider(Spider):
rules = ()
def __init__(self, *a, **kw):
super(CrawlSpider, self).__init__(*a, **kw)
self._compile_rules() #首先调用parse()来处理start_urls中返回的response对象
#parse()则将这些response对象传递给了_parse_response()函数处理,并设置回调函数为parse_start_url()
#设置了跟进标志位True
#parse将返回item和跟进了的Request对象
def parse(self, response):
return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True) #处理start_url中返回的response,需要重写
def parse_start_url(self, response):
return [] def process_results(self, response, results):
return results #从response中抽取符合任一用户定义'规则'的链接,并构造成Resquest对象返回
def _requests_to_follow(self, response):
if not isinstance(response, HtmlResponse):
return
seen = set()
#抽取之内的所有链接,只要通过任意一个'规则',即表示合法
for n, rule in enumerate(self._rules):
links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]
#使用用户指定的process_links处理每个连接
if links and rule.process_links:
links = rule.process_links(links)
#将链接加入seen集合,为每个链接生成Request对象,并设置回调函数为_repsonse_downloaded()
for link in links:
seen.add(link)
#构造Request对象,并将Rule规则中定义的回调函数作为这个Request对象的回调函数
r = Request(url=link.url, callback=self._response_downloaded)
r.meta.update(rule=n, link_text=link.text)
#对每个Request调用process_request()函数。该函数默认为indentify,即不做任何处理,直接返回该Request.
yield rule.process_request(r) #处理通过rule提取出的连接,并返回item以及request
def _response_downloaded(self, response):
rule = self._rules[response.meta['rule']]
return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow) #解析response对象,会用callback解析处理他,并返回request或Item对象
def _parse_response(self, response, callback, cb_kwargs, follow=True):
#首先判断是否设置了回调函数。(该回调函数可能是rule中的解析函数,也可能是 parse_start_url函数)
#如果设置了回调函数(parse_start_url()),那么首先用parse_start_url()处理response对象,
#然后再交给process_results处理。返回cb_res的一个列表
if callback:
#如果是parse调用的,则会解析成Request对象
#如果是rule 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 #如果需要跟进,那么使用定义的Rule规则提取并返回这些Request对象
if follow and self._follow_links:
#返回每个Request对象
for request_or_item in self._requests_to_follow(response):
yield request_or_item def _compile_rules(self):
def get_method(method):
if callable(method):
return method
elif isinstance(method, basestring):
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) def set_crawler(self, crawler):
super(CrawlSpider, self).set_crawler(crawler)
self._follow_links = crawler.settings.getbool('CRAWLSPIDER_FOLLOW_LINKS', True)

CrawlSpider继承于Spider类,除了继承过来的属性外(name、allow_domains),还提供了新的属性和方法:

CrawlSpiders模块的使用的更多相关文章

  1. 11.CrawlSpiders

    CrawlSpiders 通过下面的命令可以快速创建 CrawlSpider模板 的代码: .scrapy startproject tencentspider .scrapy genspider - ...

  2. 爬虫框架Scrapy之CrawlSpiders

    CrawlSpiders 通过下面的命令可以快速创建 CrawlSpider模板 的代码: scrapy genspider -t crawl tencent tencent.com 上一个案例中,我 ...

  3. scrapy之CrawlSpiders

    CrawlSpiders 通过下面的命令可以快速创建 CrawlSpider模板 的代码: scrapy genspider -t crawl loaderan cnblogs.com class s ...

  4. CrawlSpiders简介

    转:https://www.cnblogs.com/ellisonzhang/p/11124516.html#4295547 一.CrawlSpiders类简介 通过下面的命令可以快速创建 Crawl ...

  5. npm 私有模块的管理使用

    你可以使用 NPM 命令行工具来管理你在 NPM 仓库的私有模块代码,这使得在项目中使用公共模块变的更加方便. 开始前的工作 你需要一个 2.7.0 以上版本的 npm ,并且需要有一个可以登陆 np ...

  6. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  7. ES6模块import细节

    写在前面,目前浏览器对ES6的import支持还不是很好,需要用bable转译. ES6引入外部模块分两种情况: 1.导入外部的变量或函数等: import {firstName, lastName, ...

  8. Python标准模块--ContextManager

    1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...

  9. Python标准模块--Unicode

    1 模块简介 Python 3中最大的变化之一就是删除了Unicode类型.在Python 2中,有str类型和unicode类型,例如, Python 2.7.6 (default, Oct 26 ...

随机推荐

  1. Codeforces Round #443 Div. 1

    A:考虑每一位的改变情况,分为强制变为1.强制变为0.不变.反转四种,得到这个之后and一发or一发xor一发就行了. #include<iostream> #include<cst ...

  2. Hat’s Words HDU - 1247 字典树

    题意:给出数个单词 输出单词 如果该单词 是由字典中的单词组成的 思路:字典树 先把全部建树  然后对于每一个单词进行分割,分别拿两半到字典树里面去找 小心RE! #include<bits/s ...

  3. scrapy入门与进阶

    Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非 ...

  4. mysql 导入sql 2006 - mysql server has gone away 导入

    解决办法:找到你的mysql目录下的my.ini配置文件,加入以下代码 max_allowed_packet=500M wait_timeout=288000 interactive_timeout ...

  5. dll 修复....

    之前在安装时总是会碰到缺少什么dll文件,总是头疼的要命,这次很幸运的在网上搜到了这个神奇的小玩意,只需要运行就能够修复缺少的所有的dll文件,所以在这小小的分享一下. 链接:https://pan. ...

  6. 树莓派播放网络磁盘MP3文件

    树莓派映射网络磁盘 sudo mount -t cifs -o username=jerry.huang,password=Hello2014 //10.10.0.1/Public/ESLPod.co ...

  7. NOIP2018 差点退役记

    Day 1 不想说了,反正就是三个水题,直接来讲Day 2. Day 2 一上来,T1做法写的丑了点,折腾了一会,大概50min的样子写完了. T3一眼DDP--这玩意儿我就写过一个模板,还只写过一次 ...

  8. 自学华为IoT物联网_09 OceanConnect业务流程

    点击返回自学华为IoT物流网 自学华为IoT物联网_09 OceanConnect业务流程 1.  物流网重要的连个协议介绍 1.1  重要物联网协议介绍----MQTT MQTT(消息队列遥测传输) ...

  9. Android GPS定位测试(附效果图)

    今天因为工作需要,把以前编写的一个GPS测试程序拿出来重新修改了一下.这个程序说起来有些历史了,是我11年编写的,那时候学了Android开发没多久,算是一个实验性的作品.现在工作需要,重新拿出来修整 ...

  10. luogu5022 [NOIp2018]旅行 (dfs)

    m=n-1的时候,就直接贪心地dfs就可以 m=n的话,就可以枚举删掉一条边,然后照着m=n-1做 $O(n^2)$大概能过 (然而我眼瞎看不到m<=n) #include<cstdio& ...