别再滥用scrapy CrawlSpider中的follow=True
对于刚接触scrapy的同学来说, crawlspider中的rule是比较难理解的, 很可能驾驭不住. 而且笔者在YouTube中看到许多公开的演讲都都错用了follow这一选项, 所以今天就来仔细谈一谈.
首先我们看scrapy中的follow是如何实现的:
# 为了方便理解, 去除了不必要代码
def _requests_to_follow(self, response):
"""遍历rules, 使用rule提取response中的链接
每个rule中提取的链接都会被添加到集合中
相同的链接只会被提取一次, 也就是范围大的rule 会覆盖范围小的rule
使用提取到的链接发送请求, 得到response
"""
seen = set()
for n, rule in enumerate(self._rules):
links = [lnk for lnk in rule.link_extractor.extract_links(response)
if lnk not in seen]
for link in links:
seen.add(link)
r = Request(url=link.url, callback=self._response_downloaded)
yield r
def _response_downloaded(self, response):
rule = self._rules[response.meta['rule']]
return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow)
首先, 在我们的定义中rules是一系列Rule对象的集合, 示例如下:
rules = (
Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),
Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
)
在源代码中, 我们可以看到:
- 遍历所有的Rule对象, 并使用其link_extractor属性提取链接
- 对于提取到的链接, 我们把它加入到一个集合中
- 使用链接发送一个请求, 并且callback的最终结果是self._parse_response
上述操作表明, 当我们follow一个链接时, 我们其实是用rules把这个链接返回的response再提取一遍.

当我们需要对response进行进一步提取的时候我们才使用follow, 它会把response用rules过滤一遍, 产生新的response.
当我们的response包含有我们需要的信息是, 直接用callback提取信息.
不要滥用follow, 因为我们提取出来的链接都会被下载, 造成了不必要的请求.
其实源代码中还解释了文档中提到的关于rules顺序的问题:
Each Rule defines a certain behaviour for crawling the site. Rules objects are described below. If multiple rules match the same link, the first one will be used, according to the order they’re defined in this attribute.
多个Rule匹配同一个链接, 只有第一个Rule会被使用, 用源代码来解释就是我们匹配到了链接已经添加到set中去重了, 所以之后的匹配都无法添加. 所以我们在使用rules时, 如果两个Rule有交集, 要注意顺序.
别再滥用scrapy CrawlSpider中的follow=True的更多相关文章
- Scrapy框架中的CrawlSpider
小思考:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二: ...
- scrapy CrawlSpider解析
CrawlSpider继承自Spider, CrawlSpider主要用于有规则的url进行爬取. 先来说说它们的设计区别: SpiderSpider 类的设计原则是只爬取 start_urls 中的 ...
- scrapy -->CrawlSpider 介绍
scrapy -->CrawlSpider 介绍 1.首先,通过crawl 模板新建爬虫: scrapy genspider -t crawl lagou www.lagou.com 创建出来的 ...
- Python+Scrapy+Crawlspider 爬取数据且存入MySQL数据库
1.Scrapy使用流程 1-1.使用Terminal终端创建工程,输入指令:scrapy startproject ProName 1-2.进入工程目录:cd ProName 1-3.创建爬虫文件( ...
- 再谈SQL Server中日志的的作用
简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅: 浅谈SQL Server ...
- 用python随机生成数据,再插入到postgresql中
用python随机生成学生姓名,三科成绩和班级数据,再插入到postgresql中. 模块用psycopg2 random import random import psycopg2 fname=[' ...
- C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】
STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对 ...
- Python爬虫从入门到放弃(十五)之 Scrapy框架中Spiders用法
Spider类定义了如何爬去某个网站,包括爬取的动作以及如何从网页内容中提取结构化的数据,总的来说spider就是定义爬取的动作以及分析某个网页 工作流程分析 以初始的URL初始化Request,并设 ...
- 一定要 先删除 sc表 中的 某元组 行,,, 再删除 course表中的 元组行
一定要 先删除 sc表 中的 某元组 行,,, 再删除 course表中的 元组行 course表 SC表 删除 course表中的 元组行,,出现错误 sc ---->参 ...
随机推荐
- python 网络篇(网络编程)
一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好.但是如果这两个程序之间想要传递一个数据, ...
- 重写page的OnInit(学习中总结的)
在写b/s框架的系统的时候,我们会发现,我们经常会在不同的网页中验证Session是否存在,,而我这里没有用Session,用的是MemCache技术,其实它就是键值对. 只不过将Memcache中的 ...
- JAVA-I/O流任务
作业地址 5. Scanner基本概念组装对象 编写public static List readStudents(String fileName)从fileName指定的文本文件中读取所有学生,并将 ...
- springmvc项目搭建五-postgresql+easyui的数据显示
上一篇虽然完成了页面的显示,但是是假数据,本篇添加了postgresql的数据库,将登陆的校验和数据的显示都通过数据库来完成. 我是在本地搭建了一个postgre的数据库,就先新建两张表吧,一个用于用 ...
- nginx开机自启动
配置步骤:1 . vi /etc/init.d/nginx2. chkconfig --level nginx 2345 on --重点 --------------------以下为nginx配置文 ...
- SSH面试集锦——不看后悔哦!
1. 谈谈你mvc的理解 MVC是Model-View-Controler的简称.即模型-视图-控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开. MVC中的模型 ...
- Luogu2737 USACO4.1麦香牛块(动态规划)
小凯的疑惑升级版.只有两个数的话不能表示的最大数是ab-a-b,显然如果可选数增加不会比这更大,所以只要答案存在一定小于256*256-2*256.在这个范围内背包即可. #include<io ...
- P1268 树的重量
题目描述 树可以用来表示物种之间的进化关系.一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树 ...
- Codeforces Round #391 div1 757F (Dominator Tree)
首先先膜杜教orz 这里简单说一下支配树的概念 支配树是对一个有向图来讲的 规定一个起点s,如果s到v的路径上必须经过某些点u,那么离s最近的点u就是v的支配点 在树上的关系就是,v的父亲是u. 一般 ...
- BZOJ4568 [Scoi2016]幸运数字 【点分治 + 线性基】
题目链接 BZOJ4568 题解 选任意个数异或和最大,使用线性基 线性基插入\(O(logn)\),合并\(O(log^2n)\) 我们要求树上两点间异或和最大值,由于合并是\(O(log^2n)\ ...