在使用scrapy爬虫做性能优化时,一定要根据不同网站的特点来进行优化,不要使用一种固定的模式去爬取一个网站,这个是真理,以下是对58同城的爬取优化策略:

一、先来分析一下影响scrapy性能的settings设置(部分常用设置):
1,DOWNLOAD_TIMEOUT,下载超时,默认180S,若超时则会被retry中间件进行处理,重新加入请求队列

2019-04-18 20:23:18 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET https://bj.58.com/ershoufang/37767297466392x.shtml> (failed 1 times): User timeout caused connection failure: Getting https://bj.58.com/ershoufang/37767297466392x.shtml took longer than 180.0 seconds..

一般来说访问一个网站都是以ms作为单位的,180S确实有些太长了,而且,由于默认设置了最大并发数为16,导致这些request没有下载到东西还一直占据着并发数,在我的日志文件中就能大量看到retry日志

2.DOWNLOAD_DELAY,该选项默认为0,即在下载是并发执行,若设置为x,则每隔  0.5*random~1.5*random 秒下载下一个url,影响当然很大,很多时候还是建议给个正值,避免直接把服务器弄炸了,而且在IP准备不充分情况下,也有利于爬虫的持续运行,对双方都有好处

3.CONCURRENT_REQUESTS ,默认为16,下载器下载的并发数,建议调高,根据scrapy发挥到cpu核心性能80~90%取适应值,若服务器有反爬措施,自身准备IP又不充足情况下,建议调低;

scrapy 是基于 twisted 的异步 IO,只用到单线程,若考虑部署一台服务器专用于爬虫,请选择更高的单核性能,关于scrapy单线程的证明:

设置CONCURRENT_REQUESTS=100,让scrapy爬取一个超过100个链接的页面,检测下载前后线程数量,windows上直接在任务管理器就能看到了,没有放对比图,就我的观测来看,爬取前后线程数量是没有增加的

4.CONCURRENT_REQUESTS_PER_IP ,下载器下载时针对每个IP的并发数,默认是0,这里0指不限制的意思,取值视IP充足情况和CONCURRENT_REQUESTS决定,若DOWNLOAD_DELAY非零,搭配使用可以实现针对IP做并发下载的download_delay,如CONCURRENT_REQUESTS=16,CONCURRENT_REQUESTS_PER_IP =3,DOWNLOAD_DELAY = 2

当前下载器正在并发下载16个Request,ip:https://201.182.248.10:8080被随机分配到4个Request中,那么有一个使用这个ip代理Request从下载队列中出局,并且在2秒钟内下一个Request携带的代理仍是这个ip时,仍然会被出局,这还是我的一个猜想,有空做一个合适的模型证明一下。

二、优化方案

在执行以下每个策略之前都会清除掉上一次保存在数据库中的item,并且重新获取一定数量的优秀代理供使用,这次优化评判标准是爬取到50条ITEM,比较哪种设置的爬虫用到的时间更短,

初始设置:

CLOSESPIDER_ITEMCOUNT = 50
DOWNLOAD_DELAY=0.5
CONCURRENT_REQUESTS = 16

结果:


用时:7分21秒

策略1:比原设置更少的DOWNLOAD_TIMEOUT

设置:

CLOSESPIDER_ITEMCOUNT = 50
DOWNLOAD_DELAY=0.5
CONCURRENT_REQUESTS = 16
DOWNLOAD_TIMEOUT = 15

结果:

用时:2分20秒

结果分析:更少的DOWNLOAD_TIMEOUT换来更多的重试次数,但是由于下载超时大大减少,使scrapy性能大大提升。这个结果同时提供一种后续继续优化思路:逐渐减小DOWNLOAD_TIMEOUT的值,使得爬虫用时减少而重试次数增加的较慢,那么这应该就是一个合适的DOWNLOAD_TIMEOUT取值

策略2:比策略1更少的DOWNLOAD_DELAY,直接注释,使用默认0延迟

设置:

CLOSESPIDER_ITEMCOUNT = 50
#DOWNLOAD_DELAY=0.5
CONCURRENT_REQUESTS = 16
DOWNLOAD_TIMEOUT = 15

结果:

用时:2分19秒

结果分析:似乎和策略1结果差别不大,应该是策略1中设置的TIMEOUT_DELAY较小,在我把策略1换更大的TIMEOUT_DELAY之后,爬取用了10多分钟,后来没等,直接关闭了,就没上结果图片了。

策略3:提供比策略2更大的CONCURRENT_REQUESTS

设置:

CLOSESPIDER_ITEMCOUNT = 50
#DOWNLOAD_DELAY=0.5
CONCURRENT_REQUESTS = 50
DOWNLOAD_TIMEOUT = 15
结果:

用时:4分25秒

结果分析:这和前面的scrapy性能分析完全不符,并发数越大应该爬取速度更快才对,现在用了原来近2倍时间。来分析一下原因,可以看到,对比策略2的日志图片,策略3请求数量明显增大,223 -- >318,重试次数也明显增大,29->101,并且,此项目中使用的ip都是从本地文件中的ip随机获得的,且并没有在获取一个ip之后删除掉这个ip,可以这样分析:并发增多 -- >携带同一ip的并发请求也增多 -- > 被ban的ip也会增多 --> redirect到firewall的请求增多 -- > Request数量增多 --> retry数量增多,这样很好解释了日志中的结果。这个结果同时提供我们启示:要想增大并发数以提高爬虫效率,必须保证单次请求IP更高有效性,为了解决这个问题,后面我会借鉴git大神写的Flask线程池,提高单次请求成功率。

策略4:CONCURRENT_REQUESTS_PER_IP,对ip做并发限制

CLOSESPIDER_ITEMCOUNT = 50
#DOWNLOAD_DELAY=0.5
CONCURRENT_REQUESTS = 16
CONCURRENT_REQUESTS_PER_IP = 1
DOWNLOAD_TIMEOUT = 15
结果:

用时:35分16秒

结果分析:scrapy对使用相同ip的并发请求的处理机制对这个结果有一定影响,更加根本原因还是和策略3一样,源于ip有效性较差,下篇我将会使用flask搭建线程池以比较这四种策略的性能差异

总结:

从本例看,策略1应该就是最好的方案了,在允许少量下载延迟的情况下,也不需要大并发,照样提供更好的性能,这也正如开头所说的,对scrapy做性能优化还是要针对具体项目,具体条件。

针对特定网站scrapy爬虫的性能优化的更多相关文章

  1. Angular 的性能优化

    目录 序言 变更检查机制 性能优化原理 性能优化方案 小结 参考 序言 本文将谈一谈 Angular 的性能优化,并且主要介绍与运行时相关的优化.在谈如何优化之前,首先我们需要明确什么样的页面是存在性 ...

  2. Web前端性能优化教程05:网站样式和脚本

    本文是Web前端性能优化系列文章中的第五篇,主要讲述内容:网站样式和脚本代码的放置位置.使用外部javascript和css.完整教程可查看:Web前端性能优化 一.将样式表放在顶部 可视性回馈的重要 ...

  3. 网站性能优化(Yahoo 35条)

    Yahoo 网站性能优化 35条 一.内容部分 尽量减少 HTTP请求 减少 DNS查找 避免跳转 缓存 Ajxa 推迟加载 提前加载 减少 DOM元素数量 用域名划分页面内容 使 frame数量最少 ...

  4. Yahoo团队经验:网站性能优化的34条黄金法则

    Yahoo团队总结的关于网站性能优化的经验,非常有参考价值.英文原文:http://developer.yahoo.com/performance/rules.html 1.尽量减少HTTP请求次数 ...

  5. Yahoo网站性能优化的34条军规

    1.尽量减少HTTP请求次数 终端用户响应的时间中,有80%用于下载各项内容,这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数,这是提高网页速 ...

  6. Yahoo网站性能优化的34条规则

    摘自:http://blog.chinaunix.net/uid/20714478/cid-74195-list-1.html Yahoo网站性能优化的34条规则 1.尽量减少HTTP请求次数 终端用 ...

  7. input屏蔽历史记录 ;function($,undefined) 前面的分号是什么用处 JSON 和 JSONP 两兄弟 document.body.scrollTop与document.documentElement.scrollTop兼容 URL中的# 网站性能优化 前端必知的ajax 简单理解同步与异步 那些年,我们被耍过的bug——has

    input屏蔽历史记录   设置input的扩展属性autocomplete 为off即可 ;function($,undefined) 前面的分号是什么用处   ;(function($){$.ex ...

  8. Yahoo! 35条网站性能优化建议

    Yahoo! 35条网站性能优化建议 Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客 ...

  9. HTML5前端(移动端网站)性能优化指南

    HTML5是一种最新发布网页构架的普遍模型,是构建对程序.对用户都更有价值的数据驱动的Web的前端技术框架,它的价值在于融合CSS/javaScript/flash等众多前端开发技术,更多的体现在对交 ...

随机推荐

  1. css 实现 左右div 等高, 同时父级div就是最高的子div的高度

    原文地址:https://www.cnblogs.com/cbza/p/7145384.html 方法一: 通过父级overflow:hidden,  自己设置padding-bottom 和 mar ...

  2. boolean表达式与在if条件中的运用

    1.boolean语句 boolean 类型的数据 有两个值 false 和true; 2.在if判断的条件语句中 例如: boolean arn =false  在if 判断的括号中可以表示为 !a ...

  3. 使用Git Bash上传代码到新的分支

    1.进入想要提交的项目,点击鼠标右键,选择"Git Bash Here" 2.输入命令,查看当前所有分支 git branch -a 3.输入命令,新建分支 git checkou ...

  4. oracle表的基本操作

    --修改名称rename l_user_info to t_user_info --添加带有约束的表 create table t_user_menu( id number(20) primary k ...

  5. 关于如何在电脑上安装adb来操作手机(Android)的方法及步骤

    1.需要真实的安卓手机: 2.安卓手机需要开启USB调试模式,允许电脑进行调试(各个手机的开启方式可能不同,不知道的自行百度): 3.电脑需要安装ADB驱动,这里提供一个下载地址:https://ad ...

  6. React基础概念

    Hello Wrold ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ); ...

  7. Oracle表空间不足;查询表空间使用率(unable to extend lob segment SYS_LOB0000076749C00006$$ by 8192 in tablespace USERS)

    查询表空间对应地址 *),) total_space from dba_data_files order by tablespace_name; //方案一:修改表空间大小(32000可改为想要的数值 ...

  8. echarts统计图Y轴(或X轴)文字过长问题解决

    echarts 统计图Y轴文字过长 在使用echarts时,出现数值非常大,Y轴又显示不下的情况就需要压缩Y轴数值刻度. 解决方法: yAxis: { type: 'value', axisLabel ...

  9. Android 开发 获取Android设备的屏幕高宽

    获得屏幕的宽度和高度有很多种方法: //1.通过WindowManager获取 DisplayMetrics dm = new DisplayMetrics(); heigth = dm.height ...

  10. one-hot编码理解

    one-hot是比较常用的文本特征特征提取的方法. one-hot编码,又称“独热编码”.其实就是用N位状态寄存器编码N个状态,每个状态都有独立的寄存器位,且这些寄存器位中只有一位有效,说白了就是只能 ...