Scrapy源代码分析-经常使用的爬虫类-CrawlSpider(三)
CrawlSpider
-
classscrapy.contrib.spiders.CrawlSpider
-
爬取一般站点经常使用的spider。其定义了一些规则(rule)来提供跟进link的方便的机制。 或许该spider并非全然适合您的特定站点或项目,但其对非常多情况都使用。 因此您能够以其为起点,依据需求改动部分方法。当然您也能够实现自己的spider。
除了从Spider继承过来的(您必须提供的)属性外,其提供了一个新的属性:
-
rules: Rule对象集合。定义了提取须要跟进url的一些规则。
-
parse_start_url(response):start_url的回调函数,返回Item或者Request对象的迭代。
-
基本函数的调用顺序和Spider类一样。见(Spider类源代码分析)
-
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)
Scrapy源代码分析-经常使用的爬虫类-CrawlSpider(三)的更多相关文章
- ffdshow 源代码分析 9: 编解码器有关类的总结
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- ffdshow 源代码分析 8: 视频解码器类(TvideoCodecDec)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- Juce源代码分析(九)应用程序基类ApplicationBase
在前面的几篇文章,分析的都是Juce库里面Core模块的内存部分,除了骨灰级C++爱好者之外,貌似大家对这些都不是非常感兴趣.相信大家更想知道Juce是怎么用于产品开发,而对于它的构成不是非常感兴趣. ...
- ffdshow 源代码分析 7: libavcodec视频解码器类(TvideoCodecLibavcodec)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- ffdshow 源代码分析 6: 对解码器的dll的封装(libavcodec)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- ffdshow 源代码分析 5: 位图覆盖滤镜(总结)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- ffdshow 源代码分析 4: 位图覆盖滤镜(滤镜部分Filter)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
随机推荐
- K8S-删除Terminating状态的namespace
kubernetes 删除Terminating状态的命名空间 1.检查该namespace下是否还有资源: kubectl get all --namespace=cattle-system 2.删 ...
- POJ 1010 题目翻译+题解
题目实在是太难懂了,我翻译了一下... STAMPS Description Have you done any Philately lately? 你最近有没有集邮? You have been h ...
- Web Api跨域登录问题
最近项目第一次尝试使用web api,照搬了一般mvc的Forms登录方式,在和前端对接的时候出现一个问题: 前端使用ajax调用登录接口完成登录后,再调用别的接口,被判断为未登录. 如果直接在浏览器 ...
- HTML学习(2018.1.18)
1, 转义字符 转义字符:用于表示网页中的特殊字符 XHTML不直接输入符号,建议使用转义字符.  ------空格: ©------版权: & ...
- 【Linux】七种文件类型
Linux中的七种文件类型 d 目录文件. l 符号链接(指向另一个文件). s 套接字文件. b 块设备文件,二进制文件. c 字符设备文件. p 命名管道文件. - 普通文件
- JQuery特效之心形图片墙
效果如图: 代码如下: <!doctype html> <html lang="en"> <head> <meta charset=&qu ...
- VS2013配置编译Caffe-Win10_X64
原文链接:http://blog.csdn.net/joshua_1988/article/details/45036993 有少量修改................ 2014年4月的时候自己在公司 ...
- 【技术累积】【点】【java】【19】访问权限
java中的四种访问权限 范围如下表 权限 类内 同包 不同包子类 不同包非子类 Public ✔️ ✔️ ✔️ ✔️ 默认(Default) ✔️ ✔️ ️ Protected ✔️ ✔️ ✔️ P ...
- 【Web缓存机制系列】2 – Web浏览器的缓存机制-(新鲜度 校验值)
Web缓存的工作原理 所有的缓存都是基于一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下,未被销毁回收或者未被删除修改).这些规则有的在协议中有定义(如HTTP协议1.0 ...
- 微信小程序播放背景音乐
小程序实现和h5一样的音乐图标一直旋转. 一..js中封装旋转动画方法 添加animation属性 data:{ animation:''" } 改变animation的值(官网提供角度范围 ...