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,一经查实,立即删除!

相关文章

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…

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

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

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

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

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

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

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

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

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

状态机思路在程序设计中的应用

状态机思路在单片机程序设计中的应用 状态机的概念 状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活应用。在一个思路清晰而且高效的程序中,必然有状态机的身影浮现。 比如说一个按键命令解析程序,就可以被看做状态机:本来…

卷积核_漫画:卷积神经网络中的卷积核到底是什么?

卷积计算的直观体现如上所示,一张汽车图片经过了多次卷积操作,一开始卷积在提取低层次的特征(检测边缘),然后逐渐提取高层次的特征(完整的物体)不同的卷积探测器我们可以看到同一张图片经过不同的卷积核,得到的结果是不一样的&…

如何打开win7禁用的无线网卡服务器,Windows7如何使用批处理开启/禁用无线网卡...

对于无线网卡,Win7笔记本用户应该都不会陌生,许多笔记本用户都是在自己的电脑上安装了无线网卡之后,使用无线网络进行联网的,不过对于一些有线用户来说,无线网卡就显得并不太重要了。因此,今天小编就教大家…

超声声场模拟_超声全聚焦(TFM)简介

应读者要求,小编将介绍一下全聚焦TFM的基础知识。如有讲解不对的,欢迎批评指正。全聚焦是超声检测里面的新事物。早在2005前, Caroline Holmes、Paul D. Wilcox等国外学者就开始研究了全聚焦成像,并通过实验得出了TFM相对于常规相…

post修改服务器数据源,postgresql安装及配置超详细教程

1. 安装根据业务需求选择版本,官网下载初始化数据库执行完初始化任务之后,postgresql 会自动创建和生成两个用户和一个数据库:linux 系统用户 postgres:管理数据库的系统用户;密码由于是默认生成的,需要在系…

小程序分享到朋友圈_如何给小程序添加分享朋友圈

微信公众号更新以后,推送不是按照优先来的,你们可以把我的微信公众号点击设置为星标,以便于及时的接收信息.从微信小程序官方分享朋友圈有那么几天了,今天就分享下如何给自己的小程序添加分享朋友圈代码,几行代码的事。根据官方的提示需要基础…

JS代码大全

一、验证类 1、数字验证内 1.1 整数 /^(-|\)?\d$/.test(str) 1.2 大于0的整数 (用于传来的ID的验证) /^\d$/.test(str) 1.3 负整数的验证 /^-\d$/.test(str) 2、时间类 2.1 短时间,形如 (13:04:06) function isTime(str) …

eclipse中查看mysql_eclipse中怎样查看sqlite数据库的表

string createtable(classclazz , string tablename){//实例化一个容器,用来拼接sql语句stringbuffer sbuffer new stringbuffer();//sql语句,第一个字段为_id 主键自增,这是通用的,所以直接写死sbuffer.append("create tab…

敏捷开发之Scrum扫盲篇

现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中的各个环节&#x…

macos xampp mysql 命令_MAC系统XAMPP 中 MySQL命令行client配置使用

在PHP的学习过程中。MySQL预计是必定会接触的。MySQL的管理相信大家也会使用phpmyadmin:好吧。phpmyadmin的确是MySQL管理的神器,你想要的。他好多都有,在开发的过程中。对于后台数据库的设计架构帮助真的非常大。可是。在这篇文章的主角确不…

]Kinect for Windows SDK开发入门(六):骨骼追踪基础 上

原文来自:http://www.cnblogs.com/yangecnu/archive/2012/04/06/KinectSDK_Skeleton_Tracking_Part1.html Kinect产生的景深数据作用有限,要利用Kinect创建真正意义上交互,有趣和难忘的应用,还需要除了深度数据之外的其他数据。这…