爬取拼多多百万条商品数据

内容已更新2019.2.16

​ 一个跟导师做的项目需要拼多多的数据,就当练练手。爬完最后拿到了100万+的商品数据。(大概需要跑一天吧)github地址

没有使用scrapy或者pyspider一类的框架,因为我这个拼多多爬虫实现的方法其他都不大同。拼多多虽然没有网页版,但是有一个这个www.yankeduo.com,和app端是一模一样的,简化了抓app包分析的过程,直接分析这个网站就可以了。这个项目主要是使用selenium + 代理实现的,用selenium模拟点击,从代理中截取流通的数据包。

页面分析

​ 爬虫主要是爬取搜索界面的所有的分类,再从分类进去爬去所有商品信息。浏览器打开开发者工具,随便点击一个小分类进去

​ 就可以看到RESTful API返回的商品信息,URL类似于http://apiv3.yangkeduo.com/v4/operation/3376/groups?offset=0&size=100&opt_type=2&sort_type=DEFAULT&list_id=XXX&anti_content=XXX&pdduid=XXX而如果我们直接修改URL参数是无法正常获取数据的(就算修改size都不行)。

整个URL唯一无法破解的就是那个anti_content字段,强行破解了一下午无果后决定用selenium来模拟点击。但它并不是所有信息都会放在最终页面上的,所以如果仅仅使用selenium是无法得到所有数据的。然而这么好的RESTful API也不能浪费了,于是决定采用selenium连接代理,模拟点击的过程中从代理中获取到API返回的商品数据。

选择代理

​ 一开始想自己搭http代理,但是后来发现还得加上https。太麻烦了,学习成本有点高,决定去github上找轮子。不久就找到了一个BaseProxy,使用简单,也有开发的接口,集成到项目中很方便。

开始爬取

pddSpider

主要文件是Spider.py和seleniumoperate.py。

Spider.py继承proxy.py(也就是BaseProxy代理项目),运行代理,指定拦截函数拦截特定response,将返回的商品信息解析存入数据库。

seleniumoperate.py 就是模拟点击操作,首先先连接代理,并实现了对于搜索分类页面所有的小分类的调度爬取,_loadState()和_saveState()函数为了保存状态断开不用重新爬取了。

其他文件就如文件名一样的直接,capcha.py功能是与打码平台交互,dboperate.py是数据库操作类,threadpool.py是线程池类。state是保存的状态文件。
​ 代码都在github上,可以去看看。

验证码问题

​ 验证码确实是一个烦人的问题,自己写的很简单的普通orc识别几乎识别不了。在github上找到的一些机器学习识别验证码的项目大都需要几万张图片来训练,才能达到比较好的效果,但是让我一个人手动打码打几万张是不大可能的。所以最后还是选择了网上的打码平台。经过优化访问后可以实现五到八分钟才出现验证码。这样我花了五六块钱左右的网络打码费就把商品全部爬下来了。

在seleniumoperate.py中实现了验证码的CaptchaMonitor类。当一个号多次访问是,它会出现提交了验证码后不断的重复出现验证码,无休止的提交验证码。所以注册了7个号来随机使用,在CaptchaMonitor类中也实现了抑制短时间重复提交验证码的措施,防止白白使用了打码次数。

selenium 爬取被识别问题

​ 在我发完这篇博客后,有很多朋友也尝试了我github上的代码。后来我发现,拼多多增加了一些反爬策略,我的代码已经被拼多多的反爬策略过滤了。作为一个好学的同学,我当然要深入研究一下啦。

首先,selenium+geckodriver 是通过模拟火狐浏览器访问的,以此欺骗目标网站就好像是人为点击的一样。可是当我再跑我的代码时,发现人工点击和selenium效果是不一样的,当使用selenium模拟时,不断会出现错误界面。经过查询,selenium在运行的时候会暴露出一些预定义的Javascript变量(特征字符串),例如”window.navigator.webdriver”,在非selenium环境下其值为undefined,而在selenium环境下,其值为true(如下图所示为selenium驱动下Chrome控制台打印出的值)。当然,还有其他很多变量,大家可以看看这篇文章

那么我们重新理清思路,我们通过selenium模拟点击并连接代理,从代理中截取商品数据。而拼多多通过js文件判断我们是否使用selenium,并且将判断结果发送给服务器,控制返回内容。我们很难找到判断结果是以何种方式发送给服务器的。但我们可以从代理中截取该js文件,改变其内容,将判断selenium在js中预设的变量的部分删除掉就行了。
所以我在新代码中添加了一些代码:

 

10 thoughts on “爬取拼多多百万条商品数据

  1. 你好,我在github上看到你关于拼多多爬虫的项目,有几个问题想请教一下:
    1. 请问整个项目要运行起来的话,要怎么操作,我目前是把所有的包都安装上了,数据库也根据代码建好了,但是运行spider.py的话,程序没有报错,但是并没有开始抓取数据,请问这是什么原因?
    2. 我之前的思路是用selenium模拟浏览器打开网址,登录输入手机号并手动获取验证码,但是可能是被识别出浏览器登录手机收取不到验证码,我看你的代码中好像并没有手机号登录这部分的内容,请问模拟登录这块具体要怎么操作?
    3. seleniumoperate.py中使用的是firefox,为什么都没有设置geockdriver的路径之类的代码?爬虫渣= =
    希望能够解答我的疑问!非常感谢!

    • 1.spider.py是把代理跑了起来,还要在另一个窗口把seleniumoperate.py跑起来,分开来可以很好的看到输出。
      2.登陆这方面我是在cateGoods()函数中刚启动时有添加cookie,就是随机从上面的tokens里选一个值组成cookie,token值就是自己浏览器访问时cookie中带的PDDAccessToken。最好多弄几个号,就可以防止验证码出现太快的问题。
      3.我直接把geockdriver加到/usr/bin文件夹里面了,你也可以直接将geockdriver的路径加到环境变量中就不用设置路径了。
      共勉!

      • 非常感谢你的帮助!代码已经可以成功运行了!
        但是在爬取三十个分类左右的数据以后,拼多多那里开始出现ip访问过于频繁的提示,然后验证码的图片已经显示不出来了导致程序中断,要么就是不断的输入验证码,我尝试更换了另外几个手机号的tokens进行爬取,然后也尝试在baseproxy那里更换ip,但是还是无法继续爬取数据,请问应该如何解决这个问题?
        谢谢谢谢你!!!!

        • ip访问频繁的问题我在爬商品时没有遇到,如果你频繁遇到。我们用的baseproxy这个代理似乎不支持连接代理,那么应该就连不了IP池。如果不更换代理软件baseproxy,那么只能在外部加代理了(比如proxychains,比较麻烦,如果很频繁建议试着换一个能连接代理的代理软件TAT)。
          验证码到后面的确会不断的请求输入。我处理selenium是根据爬每个小分类开一个窗口,我在seleniumoperate.py的CaptchaMonitor类限制了每个窗口输入验证码的最短间隔,否则直接销毁窗口重新开启一个(重新开启仅仅会换一个token访问,实验证明效果还可以)。如果你还有问题,可能是cookies池的token少了一点(我当时是7个)。你也可以在适当的地方加延时,也可以减少验证码的出现。如果你愿意的话,我可以加你QQ共同讨论一下。

牛冲天进行回复 取消回复

电子邮件地址不会被公开。 必填项已用*标注