博客地址:从京东"窃取"150+万条数据
github 地址: jd_spider
使用 scrapy, scrapy-redis, graphite 实现的京东分布式爬虫,以 mongodb 实现底层存储。分布式 实现,解决带宽和性能的瓶颈,提高爬取的效率。实现 scrapy-redis 对进行 url 的去重 以及调度,利用 redis 的高效和易于扩展能够轻松实现高效率下载:当 redis 存储或者访问速 度遇到瓶颈时,可以通过增大 redis 集群数和爬虫集群数量改善
获取 <a href>
标签里面的 url 值,然后迭代爬取,并且把 url 限定在 xxx.jd.com
范围内,防止无限广度的问题。
通过禁用 cookie, 服务器就无法根据 cookie 判断出爬虫是否访问过网站
要说最著名的爬虫是谁?肯定是搜索引擎,它本质上也是爬虫,而且是非常强大的爬虫。 而且这些爬虫可以光明正大地去爬取各式网站,相信各式网站也很乐意被它爬。 现在可以通过修改 user-agent 伪装成搜索引擎
'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)', 'Mozilla/5.0 (compatible; Bingbot/2.0; +http://www.bing.com/bingbot.htm)', 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)', 'DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)', 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)', 'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)', 'ia_archiver (+http://www.alexa.com/site/help/webmasters; [email protected])',
为了提高突破反爬虫策略的成功率,定义多个 user-agent, 然后每次请求都随机选择 user-agent。本爬虫实现了一个 RotateUserAgentMiddleware
类来实现 user-agent 的轮转
使用代理 IP, 防止 IP 被封
将分布式爬虫 stats 信息(请求个数,item 下载个数,dropItem 个数,日志)保存到 redis 中 实现了一个针对分布式的 stats collector,并将其结果用 graphite 以图表形式动态实时显示
通过 setting.py
中的 CONCURRENT_REQUESTS = 32
配置来控制并发请求数量,通过 DepthMiddle
类的 DEPTH_LIMIT=max
参数来控制爬虫的的递归深度
谢谢大家的交流和提问,在交流期间我学到了很多新的想法 :).
然后有同学对我 Github 上这个 Repo 好奇 (好奇害死猫呵),然后我就新发了一个主题来跟大家交流 浅谈Linux开发环境无缝迁移, 还有同学好奇我的博客. 我的博客是搭建在 github page上的,使用 Emacs org-mode 进行编写,在Emacs 里面编写,在 Emacs 里面发布.我是一个 Emacser :)
![]() | 1 bozong 2017-06-21 22:13:30 +08:00 via iPhone 。 |
![]() | 2 zhp521163 2017-06-21 22:16:31 +08:00 很猛! |
![]() | 3 shiny 2017-06-21 22:17:34 +08:00 代理 ip 用的是哪一家? |
![]() | 4 samray OP 欢迎大家不吝指教. |
![]() | 5 bozong 2017-06-21 22:21:31 +08:00 同问。代理 IP 来源 |
![]() | 6 samray OP ![]() 代理 IP 用的不是一家,是用这两位的项目 https://github.com/qiyeboy/IPProxyPool https://github.com/qiyeboy/IPProxyPool .只是个人感觉还是不够方便,还需要自己安装和配置环境,所以我就把这两个项目做成 docker image. 然后映射 IP 出来,通过 api 获取代理 IP. 只是 image 还有点问题,所以还没有分享出来. |
![]() | 7 xiaoyu9527 2017-06-21 22:22:23 +08:00 爬虫监控状态这个是怎么做的。 感觉很。 |
![]() | 8 bozong 2017-06-21 22:23:42 +08:00 NB |
![]() | 9 samray OP 主要是将 scrapy.spider 的 stats 保存到 Redis (单机或者是集群),然后通过将这些数据发送给 graphite 来生成监控动态图.主要参考 https://github.com/gnemoug/distribute_crawler 的做法.只是这个项目已经没有维护了,并且是 python2,所以要自己看源码做一些适配. |
10 Thoxvi 2017-06-21 22:27:37 +08:00 via Android 反反爬虫策略…? |
![]() | 11 samray OP 此外,graphite 的配置安装是很麻烦的事情,并且是不支持 windows (虽说我是 Linuxer), 所以用 docker 就非常方便.我自己就在别人做好的 graphite 基础上做了些许配置的修改然后生成新的 image 适配 scrapy+graphite |
![]() | 12 samray OP ![]() 突破反爬虫策略嘛,所以就叫反反爬虫策略.见笑了. |
![]() | 15 samray OP 一台 32Gb 内存的工作站,跑了三个实例. |
16 samray OP @fate0 其实主要的问题是免费的代理大部分都不能用,而且即使现在能用,下一分钟也可能不能用.并且以文本形式来存储代理 IP,在运行的时候将代理 IP 全部加载进内存,但是如果你的爬虫是长时间运行,代理应该很快用完.所以比较理想的是"动态"加载代理 IP. 即可以在运行时继续加载 IP. 个人小小的看法.也很感谢你的项目啦 :) |
![]() | 17 fate0 2017-06-21 23:18:35 +08:00 @samray readme 里说可以全加载到内存,只不过想体现这个程序的方便而已,我个人喜欢把所有的代理都放在 redis 里,每间隔 15min 就把 proxylist 拉下来换一批,2000+个代理,15min 内一般项目一般都够用了,用 proxylist 的优点是自己不用再维护一个 proxy pool, 缺点是没法给每个 proxy 打分统计、proxylist 上的代理,可能在某个地区没法使用。 |
![]() | 18 samray OP 其实最大的问题是,知道这一刻的代理可用,但是却完全没办法保证下一刻依旧可用.:( |
![]() | 19 misaka19000 2017-06-21 23:24:18 +08:00 不错,准备学习一个! |
![]() | 20 fate0 2017-06-21 23:27:03 +08:00 @samray 这不算什么问题吧,出现 exception 就换下一个代理,商业代理偶尔也有抽风的时候,也会出现下一刻不可用,就看换代理的频率是不是可以接收的范围内。 |
![]() | 21 supman 2017-06-22 00:04:58 +08:00 休斯顿的? |
![]() | 22 xingzhi 2017-06-22 00:46:18 +08:00 关键还是在于代理。 |
![]() | 25 samray OP @fate0 我是用这个中间件来管理代理 IP 的 https://github.com/aivarsk/scrapy-proxies,随机选择代理 IP,不可用就把代理 IP 丢了. 只是还是会出现运行到一段时间之后,代理 IP 全部被丢完的情况 |
27 gaohigh 2017-06-22 08:00:38 +08:00 厉害了, |
![]() | 28 cxh116 2017-06-22 08:07:43 +08:00 via Android 天猫难抓,禁止蜘蛛,无 cookie 直接重定向到登录页添加 cookie. |
![]() | 29 yongliang 2017-06-22 08:45:42 +08:00 不错不错,马克下 |
![]() | 30 vipwpcom 2017-06-22 08:50:22 +08:00 二话不说,丢个星 |
![]() | 31 fate0 2017-06-22 09:02:38 +08:00 @samray https://github.com/aivarsk/scrapy-proxies 这代码也是从一个文本读内容啊,完全可以自己实现一个 download middleware 从 redis 里取。 |
![]() | 32 Arrowing 2017-06-22 09:24:42 +08:00 via Android 666666,感谢楼主科普 |
33 HuangLibo 2017-06-22 09:29:31 +08:00 分布式爬虫, 看起来很好玩, 赶紧给个星 |
![]() | 34 RubyJack 2017-06-22 09:31:30 +08:00 https://36kr.com/p/5078918.html 你的爬虫会把自己送进监狱吗? |
![]() | 35 figofuture 2017-06-22 09:41:32 +08:00 mark |
![]() | 36 ajan 2017-06-22 09:49:34 +08:00 按 2017 年 6 月 1 日,《网络安全法》以及最新刑事司法解释: 未经授权爬取用户手机通讯录超过 50 条记录,老板进去最高可达 3 年 未经授权抓取用户淘宝交易记录超过 500 条的,老板进去最高可达 3 年 未经授权读取用户运营商网站通话记录超过 500 条以上的,老板进去最高可达 7 年 未经授权读取用户公积金社保记录的超过 50000 条的,老板进去最高可达 7 年 |
![]() | 37 samray OP @cxh116 爬取难度 淘宝>天猫>京东.淘宝的反爬实在太强.即使用上我提到的所有反反爬虫策略.半个小时内就会爬不动,即使爬取频率不高. |
![]() | 39 fiht 2017-06-22 09:57:10 +08:00 我后来才知道,没有调度功能的爬虫在某种意义上来说不算是分布式爬虫... 不过 redis 真的好用~~ |
![]() | 40 samray OP @fate0 我知道,所以我之前提到的文本的代理 IP 会用尽就是我在爬虫过程中实际遇到的问题.可能我表达不够清晰,让你误解了.抱歉.其实我觉得爬虫的反反爬虫策略是一个问题.还有需要重点关注的是去重.之前我写的单机爬虫我都是用布隆过滤器来实现去重.只是这个项目是分布式的,用到 redis.就直接在 redis 去重.但是感觉效率没有布隆过滤器高.尤其是我这种直接从<a>标签中爬取 URL 的策略.去重就尤其重要. |
![]() | 41 samray OP @fiht 就 scrapy-redis 而言,因为用 redis 取代了 scrapy 自带的 collection.deque,就可以把需要爬取的队列从保存到内存中变成了保存到内存数据库中,但是这个时候,原来配置 collection.deque 使用的调度器就没办法使用了,也没办法进行分布式调度,于是 scrapy-redis 重写了 scrapy 的调度器. |
42 jccg90 2017-06-22 10:15:34 +08:00 哈,别老是欺负京东了。。。搞搞淘宝天猫的试试,感觉比京东的麻烦了很多 |
![]() | 43 xiaomeimei 2017-06-22 10:20:02 +08:00 淘宝天猫阿里妈妈的那叫一个难爬。成功了几天又被封了 |
![]() | 44 samray OP @jccg90 @xiaomeimei 淘宝天猫真的欺负不动.是被欺负 :( |
45 ayiis 2017-06-22 10:25:23 +08:00 大概有 10 天了? 原来是你干的... |
![]() | 46 Ixizi 2017-06-22 10:25:44 +08:00 很强! |
![]() | 47 bozong 2017-06-22 10:27:32 +08:00 楼主,我们交个朋友吧 |
![]() | 50 samray OP @xiaomeimei 其实 QQ 空间也很难爬,想起我之前写的爬取 QQ 空间照片的爬虫. https://github.com/samrayleung/qzonePictureSpider .用了一个星期来解决登陆问题,还有需要根据 cookie 计算密钥. |
![]() | 52 myself659 2017-06-22 10:40:06 +08:00 看一下评论,涨知识了 |
![]() | 57 vjnjc 2017-06-22 11:07:20 +08:00 借楼问一下这个会触发最新的 gov 的爬虫策略吗? |
![]() | 58 samray OP 并没有了解过.. |
![]() | 59 xiaomeimei 2017-06-22 11:57:07 +08:00 @samray 直接用浏览器模拟呀 |
![]() | 60 suliuyes 2017-06-22 11:57:45 +08:00 所有的爬虫,最核心最关键就是代理 ip 的问题,其他都不是事儿。 |
![]() | 61 tcpdump 2017-06-22 12:41:45 +08:00 mark |
![]() | 62 HGladIator 2017-06-22 12:54:55 +08:00 via iPhone 我就卡在 IP 这块儿 |
![]() | 63 lanpong 2017-06-22 13:10:23 +08:00 github 上 README 的博客地址指向不对。。。 |
![]() | 65 samray OP @xiaomeimei 相信你指的应该是 PhantomJS 和 selenium 配合使用来模拟浏览器,但是这样对于爬虫来说实在太耗费资源了,相当于打开一个没有 GUI 的浏览器,然后解析需要爬取的页面.这个只能作为不是办法的办法了. |
![]() | 66 samray OP @suliuyes 其实,并不是那么绝对的,例如爬淘宝,即使你经常换代理 IP,也没办法突破它的反爬策略,因为爬虫无论怎么慢,对比人来说,操作都太快了.再比如爬取 QQ 空间,并不是简单的模拟请求登陆就可以了,再你登陆之后,服务器会在 cookie 中返回三个值 p_skey,skey,rv2,然后作移位和与或操作得到一个 gtk 值,然后每次请求都要附上这个 gtk 值,不然都是 403. 更不要说 Google 的人机检验机制,不是人类根本用不了.代理 IP 是一个关键点,但是并不是全部.如果你爬取的网页超过 1000 + w,光是去重就是一个值得深究的问题了.个人小小愚见 :) |
![]() | 67 samray OP 附加一个个人推测,但未证实.在双11或者是 618 搞活动的时候,电商网站的反爬虫策略一般都会关闭,或者不会那么严格,因为面对洪峰一样的流量,需要把尽量多的资源用于处理客户端请求,而越复杂的反爬机制,需要的验证就越多,耗费的资源也会相应增加.不过这个只是个人主观感觉+合理推测,未证实. |
![]() | 68 fate0 2017-06-22 14:16:05 +08:00 @samray 1000+w 的数据去重也可以用 bloom filter 啊,就用 Redis 的 bitmap 存 bit 数组就可以了。 |
![]() | 69 shew2356 2017-06-22 14:29:59 +08:00 @ajan 第六十四条 网络运营者、网络产品或者服务的提供者违反本法第二十二条第三款、第四十一条至第四十三条规定,侵害个人信息依法得到保护的权利的,由有关主管部门责令改正,可以根据情节单处或者并处警告、没收违法所得、处违法所得一倍以上十倍以下罚款,没有违法所得的,处一百万元以下罚款,对直接负责的主管人员和其他直接责任人员处一万元以上十万元以下罚款;情节严重的,并可以责令暂停相关业务、停业整顿、关闭网站、吊销相关业务许可证或者吊销营业执照。 违反本法第四十四条规定,窃取或者以其他非法方式获取、非法出售或者非法向他人提供个人信息,尚不构成犯罪的,由公安机关没收违法所得,并处违法所得一倍以上十倍以下罚款,没有违法所得的,处一百万元以下罚款。 中华人民共和国网络安全法 http://www.npc.gov.cn/npc/xinwen/2016-11/07/content_2001605.htm |
![]() | 70 dallaslu 2017-06-22 14:33:46 +08:00 我怎么记得京东基本不限制爬虫呢? |
![]() | 71 samray OP @fate0 在这个项目中,我是直接用 scrapy-redis 来,而 scrapy-redis 是把 request 的指纹保存起来进去去重的.只是感觉这样的做法不是很符合我自己的做法,因为就我看来,去重应该是直接对 url 去重.感觉这是不同的取舍,所以感慨一下. |
![]() | 72 samray OP @fate0 我倾向于使用的就是 bloomfilter,只是当变成分布式爬虫的时候,可能会因为分布式的设计不一样而导致不一样的问题出现.单机使用 bloomfilter 和分布式不一样,可以新建一个 master 节点,然后所有的需要爬取和已爬取的 url 都保存在 master,然后 slave 节点只需请求待爬 url 就好.但是这种方式不同于 scrapy-redis,就需要自己使用 bloomfilter 以及编写调度器 |
![]() | 73 fate0 2017-06-22 15:02:36 +08:00 @samray 可能我说的不清楚,我现在说的就是分布式爬虫的情况,可以稍微修改一下 scrapy-redis 里的 dupefilter 文件,不使用之前 redis set 去重的方式,在这里改成使用 bloom filter,将 bloom filter 所使用的 bit 数组用 Redis 的 bitmap 进行存取。其他地方不需要修改。 |
![]() | 74 fate0 2017-06-22 15:04:06 +08:00 @samray 另外使用整个 request 进行 hash 还是 只使用 url 进行 hash,也可以在 dupefilter 里修改,都不是特别难。 |
![]() | 76 doggg 2017-06-22 18:39:24 +08:00 非常酷。这几天用 java 写 php 期末商城作业。只会一点 node 和 Jsoup 的我望而却步,最后还是死皮赖脸的跟图书馆老师要了全学校的图书馆数据。 |
![]() | 78 doggg 2017-06-22 20:15:27 +08:00 @samray 平日泡图书馆比较多,跟老师比较熟。其实那个商城的数据本来想爬京东图书数据的,无奈不会 py,只会一点 node,而且图书分类获取非常麻烦,京东图书的分类太过于详细。所以跟老师要了图书馆所以的图书数据。总共 30W+ |
79 dd0754 2017-06-22 20:33:45 +08:00 爆了 |
80 MIROKY 2017-06-22 20:36:11 +08:00 感谢分享 马上回去试试=w= |
![]() | 81 binux 2017-06-22 20:47:33 +08:00 我一直认为随机 UA 就是个没卵用的东西 一般选取的 UA 都是常见的,本身访问量很大的;多你爬虫几十万还是几百万根本没区别。 如果对方能从某个 UA 的正常用户中分辨出爬虫,那么你换 UA,对方也能分辨出来。 |
![]() | 82 samray OP @binux 这个并不能完全反反爬虫,只是可以提高突破的成功率.何况这个轮转操作并不是非常复杂和耗费资源,更何况我 UA 模拟的并不是正常用户,而是搜素引擎,搜索引擎本身也是爬虫. |