前言
我们采用scrapy 爬取了一些游戏数据,这里对遇到的一些技术问题 的解决情况
项目情况
爬虫的逻辑是比较简单的,有一个进程从 任务队列中 拿到 相应的任务(一般是url),去请求,拿到html/json/…后 进行解析,解析完后自己选择做什么,比如:1,把解析后的数据存起来,2,解析后发现有想用的url,重新把这些个url当作一个任务扔到 任务队列中.
我们的爬虫任务有挺多的,如 游戏的id列表,单个游戏的详情, 游戏的价格,游戏的在线人数,游戏的评论,其它平台的游戏信息 等等.
关于在scrapy中写业务逻辑
scrapy是一个爬虫框架,https://scrapy.org/
它做了很多事情,
一个最简单的逻辑,我们在官网也能看到,只要写一段spider即可,spider主要通过对response.text(返回的html/json等)解析,然后选择是yeild一个新的请求。
在上面的逻辑中,scrapy的动作说明:
1,我们自定义一个start_urls在配置上,至于怎么去请求 ,scrapy自己处理,
2,scrapy请求完后会回调我们的spider逻辑
3,如果发现在yield request,则其会把这个request扔到 任务队列,
4,如果发现yield的是item,则会调用Item的逻辑,同时会走pipeline
5, 有一个 任务队列的轮寻, 拿到其任务然后去请求然后根据任务队列中保存的回调函数去调用.
上面逻辑的一些说明:
(1),第3点中 item是scrapy的一个概念,一般可以理解为按照其格式定义的一个类,用来存解析后的数据,pipeline则是自定义的Item处理类,常常用来如把item扔到队列或其它的工作
scrapy集群的加入?
scrapy 集群的逻辑,主要是 把任务队列 扔到redis之类的 外围 存储,然后取的时候 各scrapy进程去取.
scrapy的生产部署
scrapy 可以打包成 XXX.egg ,然后部署到 scrapyd 中
scrapyd 是一个 类似 tomcat类的服务,不过它只部署scrapyd 打成的egg包,
scrapyd 部署并不像 tomcat 把包扔到服务器,而是用http的形式 把egg上传上去 ( curl http://127.0.0.1:6800/addversion.json -F project=xxx -F version=10 -F egg=@/home/xxx/xxxx.egg)
提供了很多http的接口,如列举项目,删除项目,启动spider等 等 请查看 https://scrapyd.readthedocs.io/en/latest/overview.html
爬虫-IP代理集成
限制某一IP 访问,是一个常见的反爬机制,所以我们大部分的请求都是用IP代理.
scrapy给了非常方便的集成, 在 middlewares.py 增加一个方法,
class RandomProxyMiddleware(object):
# 动态设置ip代理
def process_request(self, request, spider):
request.meta["proxy"] = proxyaddress
即可,这个proxyaddress则一般是个 代理地址 如 http://xxxx:8888
代理服务 一般是买第三方的服务,如芝麻HTTP,luminati,代理云之类的, 也有一些免费的,但不稳定!
不同的代理服务 获取代理地址的方式不同, 不过最后都是 request.meta[“proxy”] = proxyaddress 这样来接入.
使用过的IP代理
我们用过三款代理,代理云,芝麻,luminati
我们是有比较高频次的请求,但是每个请求的流量不大,时间上,每天也都差不多,最开始是用芝麻,后面用了一段时间代理云,然后是luminati
1,芝麻代理,
刚开始,也是网上找的,感觉芝麻界面上还OK,就定了它。
使用:通过一个接口获取IP:port后存起来,这个ip是有时间限制的,看你在芝麻上的配置,可以几分钟到几十分钟不等,我们应该是高频,所以一般都是时间最短的。获取IP后存起来,然后设置失效时间(接口有返回),具体调用的时候 发现调不通了或是 429状态了,就把这个IP去掉。
价格:是按IP数收费,我们每天有小几十万的请求,平均1个IP能支持大约50100个请求,大约一天会消耗20003000个IP,芝麻的定价一个IP是0.04,一天大约是80~120块,比较贵
比较稳定
2, 代理云
感觉一天太贵了,想搞包月的,就找了代理云,这是和他们 直接谈的,2000块包月,1W+的IP,估计可以谈,具体的可看各自。
使用:和芝麻差不多,都要自己维持个IP池,
价格: 就包月费用,
比较稳定
3,luminati
这个貌似是以色列的公司,然后有很多国家的代理,但是网站有时间在国内访问不稳定。
使用:这个不需要自己维护个IP池,他们会给个域名作代理,里面会有权限信息,直接请求即可,但你不知道具体请求目标地址的IP,如果要换IP,代理地址中的SESSIONID换一个即可。使用比较方便
价格:这个有多种收费,如固定IP,和流量,我是用流量的,由于我们高频和不高的流量,我们这个省了很多钱,粗略50美元能用40天,
在国内有时稳定,要考虑好,如果你的服务器是国外的可以侧重考虑的。
遇到的反爬逻辑?
之前遇到一个steamdb的反爬逻辑,如直接访问https://steamdb.info/ ,
看请求的话,其会返回一个503的状态,同时带一个 页面,这个页面是加载状的,页面等了几秒后会跳转,跳转到我需要访问的界面
在爬虫的场景下,则我会发现有很多的503状态的返回,都爬不到自己的目标地址.
原因:
其采用了一个反爬的逻辑,即如果发现cookie没有对应的数据,则会跳到一个加载页且返回503,然后再在浏览器再跳目标页。
解决办法:
可以拿到这个 503返回的页面把cookie拿到,然后给每个请求都加上这个cookie,则可以正常访问目标页面 。
如果遇到要登陆的页面怎么做?
现在的逻辑并没有用到登陆之后去访问的,但也有所准备
登陆和上面遇到的steamdb实际上差不多,其都是带上了cookie后就可以了,
在实现上,
我们可以用scrapy的请求,用账号密码填上去一个post请求,然后把返回的cookie给后面的爬虫请求即可。
但实际上,登陆界面一般都比较复制,如有验证码之类的,所以看到是复杂的界面一般建议是用web自动化工具,如selenium 等.
用这类 自动化,然后在页面上进行登陆页面的获取,
如果是邮箱或手机号的验证码,则通过一些接口获得.
如果要验证码,可以采用第三方服务的打码工具,也可以自己做下验证码的验证,
拿到的cookie放到redis中。
说明:
这一套逻辑并没有经过正式的生产实现,所以仅供参考!