scrapy 中不同页面的拼接_scrapy使用技巧总结

1. scrapy运行过程概述

scrapy是一个基于python的网络爬虫框架,它读取对指定域名的网页request请求,截取对应域名的返回体,开发者可以编写解析函数,从返回体中抓取自己需要的数据,并对数据进行清洗处理或存入数据库。

scrapy工程的爬虫全部存放于工程二级目录下的scrapy文件夹中,使用genspider命令可以构建新的爬虫脚本,使用crawl命令可以使指定爬虫脚本运行。下面简述scrapy爬虫代码的运行过程。

实际上,scrapy有一个被提前定义好的方法start_requests(self)。在没有被重构的情况下,该方法会读取start_urls列表中的url字符串,默认使用get请求方式访问这些url,并默认回调解析函数parse。parse函数以请求得到的返回体response为参数,进行对应的解析数据操作。采用genspider命令生成的scrapy爬虫初始状态如下:

dba14d3a716642f8720adc8c0a24f17c.png

2. scrapy的使用技巧和注意事项

2.1 对多个数据源进行不同的解析处理

显然,start_urls方法和parse方法都是可以被重构的。重构parse方法,就可以更改对网页返回体的处理方式。解析函数并不是唯一的,可以自行定义多个解析函数,也并不是必须命名为parse,重构start_requests函数就能指定使用哪个函数对数据进行处理,实例如下:

092f4444de30f1fe0ed33a6880fcefc2.png

如图所示,重构start_requests方法后,对于带有baidu字符的url,callback指向第一个解析函数parse_baidu,否则指向第二个解析函数parse_jd,也就是说,start_urls中定义的两个url,会在爬虫执行的过程中经过不同的处理方式,这就是对多个不同的数据源采用不同解析方式的实现方法。

2.2 数据元素的定位

找到正确的网页元素位置是爬虫获取数据的关键。对于结构单一的静态网页,只需要采用devtools(快捷键F12)自带的元素检查功能,就能定位到元素所在的位置,根据其采用的网页设计样式,使用scrapy自带的selector进行筛选,常用的筛选器有xpath和css,这是scrapy爬虫曾经常用的传统方法。

但实际操作中,并非所有网页元素都可以通过元素检查功能进行正确定位,一些错误的理解会导致数据无法真正的定位。下面举一个例子:

340f7aeae638549e63cc8630cd16c20c.png

如图所见,如果使用devtools的元素检查功能定位“总计费用”字段的80.00数值,可以发现,数值80.00被放在了标签为“em”的网页样式中。如果单纯地认为数据已经被正确定位到html中的某个标签下,那么就大错特错了,我们打开网页源码,查找一下80.00字符串:

cacdb29544208d775425ffd36e7d184c.png

可以看到,80.00在网页源码中并不存在。

这是为什么呢?实际上,元素检查功能会将静态页面下的网页版式和所有动态生成的数据展示为一个“页面”。这个页面上的源码实际上是多个不同的网页格式和网页脚本共同生成的,它的代码并不是真正的网页源码。这种不存在于html网页的数据,实际上就是一种“动态数据”。

时下比较常用的存储动态数据的方式,一般是通过javascript脚本生成,或使用ajax异步加载。在已知数据加载类型的前提下,使用devtools的过滤器进行元素检查是更好的方式。

da1121673dc13a259936a2fcd15ed36c.png

如果数据通过ajax异步加载,则过滤器设置为XHR,如果数据采用javascript脚本直接生成,则过滤器设置为JS。还有一个比较常用的过滤器是DOC,它是用来选择静态页面的。一些数据量较小的网站可能会将页面数据直接写在html中,DOC过滤器主要应对这种小型的网站。

而我们要查找的80.00字段,它实际上是通过ajax异步加载的数据,既然是异步加载的数据,就可以通过异步请求得到,因此,反复点击页面的一些按钮,如果整个页面没有被刷新,只有一部分刷新,那么这些刷新出来的数据就可以通过设置过滤器为XHR找到。

经过查找可以发现,80.00这个数据是一个异步请求的返回体中携带的两个数据20和60的加和,如图所示:

8736dabb0eee00e8b53676bf111449f8.png

它的返回体是一个json,并不是网页标签包含下的数据,因此处理方式不能使用selector,而是需要引用json库,按包含键值对的字典操作进行处理。而它的url也不是原网页html,而是下图中红框圈出的Request URL:

2fbbf8a268f770397248e9976e9e86c3.png

用户浏览网页时,被加载的网页会自动向其它url中获取数据,因此可以得到来自很多不同的url的数据。但是爬虫不能享受这样的待遇,因此爬虫的撰写者需要额外费一番心思查找数据,依靠反复搜索,甚至需要结合html编码的经验才行。 2.3 scrapy的并发性与程序逻辑

scrapy是并行爬取框架,在默认的情况下不能用来做指定时序的爬虫。

scrapy会瞬间将start_urls列表内的数个url放入爬取队列中,爬取队列最多同时处理8个url的request请求,哪个url的请求最先得到回应,哪个url的parse方法就最先被执行,(多个parse方法不会交叉执行)。在多个url的页面结构相近的前提下,哪个页面最先返回,几乎是随机的。因此,在start_urls中定义的列表顺序某种意义上是无效的。如果一定想要scrapy顺序爬取,该怎么办呢?实际上这是一个并不常见的需求,如下几个思路可以考虑一下:

思路一,可以在settings.py中指定并发上限CONCURRENT_REQUESTS_PER_DOMAIN,默认值为8,如果设置为1,则scrapy变为顺序爬虫,按start_urls列表内各个url的排布顺序爬取,失去并发性。其效果如下图所示:

f8a004d16fe0906b47a67f683bf44f1c.png

图一是并发上限为8的情况下,反复多次对5个新闻标题的爬取结果,图二是并发上限为调整为1之后的结果,可以看到,并发上限设置为1时,新闻的多个标题爬取顺序是固定的,和start_urls的列表顺序一致。

这种方法虽然能让爬虫按照程序内的逻辑顺序执行爬取,但会使爬虫的效率降低。首先,scrapy并不擅长单页面的爬取。其次,如果将请求并发数置为1,一旦其中的某个页面由于各种原因被阻塞,则整个爬虫都会受到影响,效率大大降低。另外,settings.py是一个全局设置,更改了settings.py会使整个工程所有的爬虫发生变化。

思路二,可以手动定义多个解析函数,令这些解析函数互相显式调用。这种方法过于笨重,不推荐使用。思路三,引入其他能瞬时发出request请求的库(如requests),在解析函数中进行爬取逻辑设计。这种方法虽然看起来有点“犯规”,但不失为一种很有效的解决方式。只要不破坏scrapy框架本身的结构,进行这样的设计是完全没有问题的。

这些设计思路都是为了解决scrapy按顺序爬取多个数据源的问题,但是这也必然会引发“单通道阻塞”的传统问题。这是一个逻辑问题,与框架结构无关,因此不可避免。需要注意的是,scrapy依然是以多线程并行处理能力见长的爬虫框架,设计爬虫时要尽可能扬长避短。

14646f857a44728f9e056e1344601b94.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021南京大学计算机复试线,南京大学2021年硕士研究生复试基本分数线

南京大学2021年硕士研究生复试基本分数线一、学术学位报考学科门类总分第1门第2门第3门第4门备注哲学[01]33555559090各院(系、所)综合考虑生源情况、本学科、专业人才培养特点及复试比例要求,根据学校复试基本分数线,可上调本院(系、所)复试的成绩要求。…

Buffers, windows, and tabs

If you’ve moved to Vim from an editor like Notepad or TextMate, you’ll be used to working with the idea of tabs in a text editor in a certain way. Specifically, a tab represents an open file; while the tab’s there, you’ve got an open file, as soon as y…

js如何获取计算机当前时间,js获取当前系统时间

搜索热词下面是编程之家 jb51.cc 通过网络收集整理的代码片段。编程之家小编现在分享给大家,也给大家做个参考。var myDate new Date();myDate.getYear(); //获取当前年份(2位)myDate.getFullYear(); //获取完整的年份(4位,1970-????)myDate.getMonth(); //获取…

docker访问宿主机mysql_docker容器内访问宿主机127.0.0.1服务

点击上方”技术生活“,选择“设为星标”做积极的人,而不是积极废人背景原因分析解决方案背景已经通过docker启动的elasticsearch 服务,监听端口9200。在宿主机中直接通过http://127.0.0.1:9200 可以直接访问,但是通过docker访问缺…

ADO.NET+Access: 3,参数 @departmentName 没有默认值

ylbtech-Error-ADO.NETAccess: 3,参数 departmentName 没有默认值。1.A,错误代码返回顶部 3,参数 departmentName 没有默认值。1.B,出错原因分析返回顶部未解决1.C,相关解决方法返回顶部作者:ylbtech出处:http://ylbtech.cnblogs.com/本文版权归作者和博…

lombok有参构造注解_Java高效开发工具: Lombok

Lombok, 一个Java开发必备效率工具,可以大大避免编写一些常用方法(get/set, hashcode等),简化开发。虽然现在IDE很多都可以通过快捷键生成POJO的一些方法了,但是如果该POJO字段发生变动后,还是需要程序员再次手动重新生成相关方法…

JavaScript操作大全整理(思维导图三--函数基础)

3.JavaScript函数基础 转载于:https://www.cnblogs.com/yuxia/p/3360806.html

__attribute__ 之weak,alias属性

Weak Alias 跟 Weak Reference 完全没有任何关系,不过是我在看到 Weak Reference 的时候想到的而已。 Weak Alias 是 gcc 扩展里的东西,实际上是函数的属性。这个东西在库的实现里面可能会经常用到,比如 glibc 里面就用了不少。抄录一段 gcc …

nginx指定配置文件启动_NGINX安全加固手册

NIGNX系统安全基线规范1.概述1.1 适用范围本配置标准的使用者包括:各事业部服务器负责人。 各事业部服务器负责人按规范要求进行认证、日志、协议、补丁升级、文件系统管理等方面的安全配置要求。对系统的安全配置审计、加固操作起到指导性作用。1.2 文档内容本文档…

口袋网咖已有服务器在使用怎么注销,口袋网咖_口袋网咖常见问题_口袋网咖专区...

口袋网咖是专门为游戏高玩打造的手机变电脑软件,虚拟电脑神器,体验各种电脑游戏,非常的方便,能让小伙伴尽情的体验手机电脑的感觉,很多小伙伴在使用过程中遇到了一些问题,快啦网为大家分享口袋网咖常见问题…

p

都不知道简历去投什么地方。游戏都卖不出去,又做不出口碑好的。这些人是心存侥幸还是心存坚持。 感觉自己搞不清楚就很难再出发。转载于:https://www.cnblogs.com/YOUEN/p/3364227.html

bbb u-boot 验证 emmc

目标: 参考"common/cmd_mmc.c"的查找emmc的代码,在mmc总线初始化函数后,遍历mmc总线,查找emmc并 打印emmc信息。 在"drivers/mmc/mmc.c"中的mmc_initialize函数的最后面添加我们的遍历函数 int mmc_initia…

统计个人已完成的工作量_团队工作量及团队价值贡献统计、核算、评审及提升的重要性...

在推行阿米巴经营模式时,需要进行企业内部产品及服务全价值分析,也就是企业内部团队产品及服务价值增值的全过程分析,团队价值增值是团队存在的目的和意义,对于团队经营来讲,团队工作量就团队的收入,团队价…

hyper服务器虚拟网卡和实际网卡,Hyper-V 3 虚拟网卡带宽应用限制

Windows Server 2012的Hyper-V 3中,打来了系列新功能,例如网卡流量限制功能。 基础架构注意的问题宿主服务器规划过程中,管理员主要考虑服务器基础架构中的CPU、内存、磁盘空间等必要因素,但是网络适配器(简称网卡)通常属于被忽略…

数据结构--------------静态表的希尔排序

#define LT(a,b) ((a)< (b))#define EQ(a,b) ((a)(b))#define LQ(a,b) ((a)<(b)) typedef struct ElemType{//表中元素结构 int key; char name[20];}ElemType; typedef struct SSTable{//静态表结构 ElemType *elem; int length;}SSTable; ElemType r[20];//全局变量,用…

智能集群理论优化控制_数学学科学术报告九:机器人集群的智能协同控制方法_中国计量大学...

数学学科学术报告九&#xff1a;机器人集群的智能协同控制方法_中国计量大学中国计量大学 免费考研网/2018-05-17报告题目&#xff1a;机器人集群的智能协同控制方法报告人&#xff1a;孙长银(东南大学 教授)报告时间&#xff1a;2018.04.09 15:30-16:30报告地点&#xff1a;格…

css复选框如何调大一些,创建CSS放大复选框

您可以随时使用复选框来勾选自己的复选框.这允许更多的跨浏览器兼容的解决方案.我做了一个快速演示here,显然你必须得到一个透明的.png的滴答,而不是我得到的.input[typecheckBox]:checked ~ div label{background: url(http://ramyasspace.files.wordpress.com/2011/06/tick.j…

outside of class is not definition

有一种可能的情况&#xff1a;You have semicolons (;) at the end of all your function definitions making the compiler think theyre declarations. 即在方法定义的后面都误添加上了";",导致编译器认为这仅仅是个声明。

Makefile中=、:=、+=、?=的区别

&#xff0c;就是基本的赋值 :&#xff0c;覆盖原来的值 &#xff0c;添加新值 ?&#xff0c;如果没有赋值则赋值转载于:https://www.cnblogs.com/wangluojisuan/p/3369072.html

用python画面积图_Python笔记:用matplotlib绘制面积图

用pyecharts绘制出来的面积图、圆环图太有个性了&#xff0c;未免感觉有点“高处不胜寒”。今晚虽然休息&#xff0c;但继用matplotlib绘制折线图之后&#xff0c;我又心血来潮地想用matplotlib来制作一点面积图&#xff0c;因为这在零售行业也是常用的可视化图形之一。具体如下…