一名热爱体感技术的
业余专业开发人员

继续爬豆瓣电影数据

有经过了一周的奋斗,使用了各种反爬虫办法,爬取到了很多豆瓣数据,目前继续爬豆瓣电影是否能播放的信息。爬豆瓣不是一件简单的事情,需要经历过多个步骤才能爬取到比较完整的电影信息。目前爬取到了20W条电影、电视剧信息(肯定是不完整的),其中有16W是电影的数据。还不知道如何更新数据库,一旦豆瓣录入新的电影信息,我是没办法知道的,因为新电影信息的api需要毕竟高级的权限才行,普通人别想获取到。这么看,要想更新只能全站重新爬取一遍了。

说说这次爬虫实战学到的新技巧、新技术吧。

首先爬取所有信息(目标20W的数据),要想在毕竟快的时间内爬取,必须使用多线程+代理IP这类技巧,否则得爬很多天。由于分好几个阶段爬数据,多线程设计也不一样。

第一阶段爬取subject id信息,我对每个tag设置一个线程爬取,目前一共试了200来个tag,当然大部分tag内容是重复的,但是没办法,不得不这样爬。当然不是说一开始就开200个线程,如果那么开,代理ip池根本不够用啊。大概每次爬50来个tag,过一段时间发现二三十个线程爬完了,终止下,在增加点tag继续爬。反复如此,经过几天才爬取完毕。

第二阶段爬取每个影片主要信息,这时sqlite数据库已经有20W+数据,我开了十个线程爬,比如第一个线程就爬第1、11、21、31、……条数据库对应的电影信息,其他也如此。这一步和上一部爬取方法毕竟相似,都是搞api,解析json保存即可。但是在爬取的途中不断发现新的问题,如有些电影就是不存在,还爬它就死循环了。有的电影多个id对应一个url,也就是同一个电影,由于设置了url index唯一,插入数据库报错。等等这类问题,只有不断爬取才会知道,官方api也没有给出解释的。

第三阶段爬电影、电视剧能否播放信息,就更有趣了。首先,用移动端app知道有特定的页面可以显示这条信息,爬这个页面会大大节约时间(内容少呗)。然后开始爬取,发现会自动跳转到pc的内容,想到服务器一般是通过agent head识别是否是移动设备的。于是去github找了移动设备的agent,这里再提一点,移动设备的agent竟然没有专门的仓库来给大家封装,如果谁弄个这样的虚假agent肯定会得到很多star。不过这个信息,只能用https爬,我发现用普通的代理池爬取完全失效,而用代理池爬这条信息发现池子长久没有可用的ip。没有办法,花了9块钱,在大象代理ip处购买了包日服务。果然花了钱的ip池果然好太多,完全满足单机爬取需求。直接花钱用的ip池就不用额外开一个程序搞池子了。

其他经验:

1.爬取http地址,代理ip池子建议设置得越大越好,网上默认设置的50在多线程下完全不够用。

2.爬https信息,可能只能花钱了,免费中可用的非常非常少,爬了10分钟就三四个可用的,程序根本跑不起来。

3.使用cmd跑python程序会比pycharm里跑爬虫程序快很多。(刚发现的)

4.操作sqlite记得加锁,反正我不管读写无脑都加锁。不然多线程会把数据库弄崩了~

5.数据库高读写时,尽量不要额外打开数据库了,不然sqlite说自己太忙,然后就卡住了~不过数据库不会损坏,最多一些数据爬到了没保存进去。(这时候可能最后还需要一个程序进行查缺补漏,正对那些没数据的行重新爬下。)

6.实践出真知,一开始设计的多线程非常难读也难维护,写多了就知道哪里肯定会出异常,在出异常之前就考虑好是否要加个while True,不然不让跳过这次爬取。(跳过了会有很多空数据) 出了异常要怎么办,一般都是重新爬取,重新爬取前一般要更新代理,agent头之类的。

爬取好信息只是第一步,后面如何用好这些数据,如何优化sql语句,优化搜索结果又可以搞很久~