Tommy Dai

Love Coding Love Life

从零开始学Python爬虫之scrapy

2018-04-09 by Tommy Dai


从 scrapy 到 scrapy-splash 转到 scrapy-redis 一路踩坑填坑之旅

  • 新公司刚转正就把我调到新的部门去了,从此便自立门户。新部门就我和我老大😂
  • 老大是产品,我是开发等于就我一个人写代码…😳,折腾吧码农……
  • 第一个需求就是爬取指定微信公众号发布的所有文章,幸好我之前也写过爬虫程序,可爬公众号并没有想像中那么简单,微信的反爬虫做的很好,哪怕是用户正常的操作,频率高了都会出验证码。
  • 所谓工欲善其事……,转战Python,爬虫有相当丰富的类库支持。方案成熟和丰富的类库支持是我选择Python的主要原因,Python我不会😂,踏入Get新技能的副本中不能自拔…

回想起以前2周学会Java开发项目,对于现在的Python我根本没放在心上。本文旨在叙述解决问题的思路和方法。不详细贴出具体代码实现

新手快速上手建议

1.安装PyCharm编辑器
2.安装PyCharm编辑器
3.安装PyCharm编辑器

没错,借助这个编辑器你就可以骚起来了...

scrapy 小试牛刀

  • Python开发环境安装,PyCharm下scrapy安装略过
  • 以下命令都在PyCharm命令行下敲
//创建一个scrapy项目
scrapy startproject demo
//上条命令成功执行后会创建相关文件并提示新的命令创建爬虫程序
//目录大致如下
└── demo
  ├── demo
  │   ├── __init__.py
  │   ├── items.py
  │   ├── middlewares.py
  │   ├── pipelines.py
  │   ├── settings.py
  │   └── spiders
  │       └── __init__.py
  └── scrapy.cfg


输入新的命令一个简单爬虫就完成了,目前为止还一行代码没写就得到了一个爬虫。
cd 到 demo/demo/spiders 目录下
scrapy crawl 爬虫名 //就执行了此爬虫

此爬虫适合作为计划任务去跑,我们需求是需要和前端交互,所以我放弃了这种方式,加入了scrapyd。可以通过发请求启动爬虫,并且可以传参。虽然爬虫启停是可控的了,但仍旧不太满意,scrapyd只返回爬虫启停信息并不直接返回爬虫爬取到的内容信息。另外爬取数据的过程中我发现图片信息丢失。所以有了下面的方案。

scrapy + splash

  • 我要爬取的数据来源是微信搜狗,它可以搜索到微信公众号文章。
  • splash是个轻量级浏览器内核,我用它模拟浏览器行为,比如爬取公众号文章时,必须下拉浏览器滚动条图片才显示,用splash我直接默认浏览器高度为整篇文章的高度,这样即使不下拉所有的图片也会显示出来。
  • 不好的地方是splash必须设置等待时间0.5秒,这样对爬取速度大打折扣。另外scrapy爬取到文章交给splash解析本身也增加了硬件资源消耗,增加了爬取的复杂度。

考虑到 scrapy + splash 不适合大规模的数据爬取,最后将架构改为 scrapy + redis 分布式爬虫,也就是即将出场的下一个方案

scrapy + redis

  • 以上方案我大概折腾了一周多,最后都被我自己给否定掉了。
  • 大规模的数据爬取我首要考虑的是稳定性、可扩展性、容灾性等等。
  • scrapy + redis 正好是较为合适的成熟方案,它可以是分布式的,所以可以在不同服务器上启动进程分布式爬取。这正好符合我的所有需求。
  • 我将爬虫分为两个,一个master用于爬取文章列表的url,另一个slave用于爬取master提供的url,将文章详情解析入库。
  • master爬虫用到了搜索,所以必须加入代理中间件通过ip代理去发请求,我用的是abuyun代理,虽然大部分可以代理爬取成功,但是依然有少部分的代理ip被搜狗微信屏蔽掉了,所以这部分丢失的我必须重新换代理ip重新爬取,目前还没解决。
  • slave爬虫倒是很健壮稳定,由于没有用到搜索,所以它不用加代理,轻轻松松的就爬到master提供的url里的文章详情。
  • 两个爬虫相互独立,slave几乎定下来了,一直很稳定。master只要解决了丢失问题应该问题也不大。

现在前端只要往redis里写入要爬取的公众号,master爬虫就会爬取所有文章的url,然后push到redis,slave接过master的工作继续爬取每个url下的文章,整个架构和流程简洁清晰。整个方案演变的过程中其实有大量的细节,在和搜狗微信对抗的过程中也有很多技术细节就不展开了,整个过程中我其实也是边找资料边研究。多baidu & google & 代码实践,相信没有什么问题搞不定的。

我认为很有帮助的参考资料


Share and comment