创建文件模板

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. IDM下载神器

    破解版IDM 个人评价:基本上能满足日常下载需求,除bt.磁力外. 不管是在线视频, 还是音乐, 电子书, 统统都能下载, 还附有爬虫功能~~ 直接附链接: 百度云链接: https://pan.ba ...

  2. Educational Codeforces Round 61 (Rated for Div. 2)

    A. Regular Bracket Sequence 题意:给出四种括号的数量 ((  )) ()  )( 问是否可以组成合法的序列(只能排序不能插在另外一个的中间) 思路: 条件一:一个或 n个) ...

  3. Docker容器安装

    使用脚本安装 Docker 1.使用 sudo 或 root 权限登录 Centos. 2.确保 yum 包更新到最新. $ sudo yum update 3.执行 Docker 安装脚本. $ c ...

  4. C#常用的命名规则汇总

    C#常用的命名规则汇总 来源 https://www.cnblogs.com/pengyouqiang88/p/5021128.html 本文转载自脚本之家 本文详细汇总了C#常用的命名规则.分享给大 ...

  5. 使用Putty执行Rsync命令

    背景介绍:公司的文件服务器有多个,一个Master服务器,10个左右的Slave服务器. 当Master服务器中的文件更新之后,Slave服务器中的文件也必须做相对应的同步操作. 公司目前使用的Rsy ...

  6. LOJ2557. 「CTSC2018」组合数问题

    LOJ2557. 「CTSC2018」组合数问题 这道题是我第一道自己做完的题答题.考场上面我只拿了41分,完全没有经验.现在才发现其实掌握了大概的思路还是不难. 首先模拟退火,通过了1,2,6,9, ...

  7. 【SPOJ】Power Modulo Inverted(拓展BSGS)

    [SPOJ]Power Modulo Inverted(拓展BSGS) 题面 洛谷 求最小的\(y\) 满足 \[k\equiv x^y(mod\ z)\] 题解 拓展\(BSGS\)模板题 #inc ...

  8. [luogu3246][bzoj4540][HNOI2016]序列【莫队+单调栈】

    题目描述 给定长度为n的序列:a1,a2,...,an,记为a[1:n].类似地,a[l:r](1<=l<=r<=N)是指序列:al,al+1,...,ar-1,ar.若1<= ...

  9. __init__、__new__、__call__ 方法

    __init__方法 __init__方法负责对象的初始化,系统执行该方法前,其实该对象已经存在了,要不然初始化什么东西呢?先看例子: # class A(object): python2 必须显示地 ...

  10. 【原创】【状态压缩DP】POJ3254 Corn Fields【新手向】

    一开始根本不会状压dp,上网各种找题解,但发现他们写的都很......反正我作为一个没有接触过状态压缩的,根本看不懂! 然后看了好多状态压缩的题的题解,总结了一下思路,思路很重要,有了思路转换成计算机 ...