请稍侯

python爬虫获取豆瓣电影——爬取过程介绍

01 June 2015

  我的目的是将尽可能多的电影信息从豆瓣电影中爬下来,首先我们需要做的就是起始url,结果浏览豆瓣电影相关的页面,我选择了以分类为入口(最后修改为以年代标签为入口,原因见文章最后),也就是http://movie.douban.com/tag/这个页面,以爱情这个分类为例,它的url是:
  http://www.douban.com/tag/爱情/movie
  每个页面上有15个电影,点击下一页之后,页面跳转到:
  http://www.douban.com/tag/爱情/movie?start=15
  再次点击下一页,页面跳转到:
  http://www.douban.com/tag/爱情/movie?start=30
  是不是觉得似乎发现了什么,没错,url的前面大部分信息是没有变化的,只是start=后面的数字发生了变化,每次增加了15,至于为什么是15,因为每个页面上有15个电影。所以我们只需要从http://www.douban.com/tag/爱情/movie?start=0开始,爬完这个页面之后就将start=后面的数字加上15便可以实现翻页的功能。
  翻页的功能解决之后接下来就是获取这个页面上列出的15个电影的相关信息了。以http://www.douban.com/tag/%E7%88%B1%E6%83%85/movie?start=0这个页面为例,我们通过chrome浏览器的开发者工具查看页面,如下图所示:
1
  从页面源代码中我们可以看出,页面上的15本书都在<div class='mod movie-list'></div>这个div中,每本书都对应一个<dl>,如下图所示:
2
  在<dl>中有用的信息主要有:电影的url、评分以及简要分类和演员信息,可是这些信息太笼统了,我想获得更加详细的信息,包括演员、国家、简介等信息。此时有两种方法可以获取:
——plan A:通过已有的url,跳转到电影介绍的相关页面,爬取相关的内容; ——plan B:通过调用豆瓣的API获取电影的相关信息。
  这两种方法我都试了下,由于在电影介绍的相关页面的源代码中获取电影相关信息比较麻烦(主演、导演等电影信息的html代码区分度不高导致抓取较为麻烦,我实现了之后发现但是得到电影信息不全面),所以采用直接调用豆瓣的API的方式获取信息,豆瓣API返回的信息为JSON格式,选取其中部分信息存储至数据库中就可以了。
  由于豆瓣的API是有访问限制的,如果只是想试验一下API,豆瓣也允许在不申请API Key的情况下进行API调用。不过在这种情况下,API调用被限制为每分钟请求不超过10次。使用API Key时,对访问的限制较为宽松,为每分钟40次,超过限制的话会被封禁,所以大部分时间都是在和访问限制进行对抗。
  下面列出在过程中遇到的一些问题以及解决办法:
  (1)首先使用的是热门标签中的标签作为输入,在测试过程中发现重复率较高,后来发现使用年代标签作为输入可以有效的降低重复率,你可以设置一个起始年代,生成直到当前年代的列表,将这个列表作为参数传递给任务函数。
  (2)每获得一个movieid,我都调用豆瓣API获取信息之后在存储到mysql的时候判断这部电影是否存在,后来改成首先冲数据库中获取所有电影的movieid放在一个列表中,每次得到movieid,先判断在列表中是否存在,存在就不需要调用API,在爬取过程的后期会大大减少API调用的次数,不存在再调用API并将movieid加到列表中。
  (3)多线程需要考虑操作的原子性,存储所有电影的movieid的列表是被若干线程共享的,由于列表的append操作是原子操作,所以在向列表中插入movieid时不需要进行加锁操作。


  陆陆续续爬完大概花了好几天,因为中途会出现API被封的情况,因为获取代理ip并检测是否可用这个功能还没实现,所以ip被封只能等个几个小时,爬完查看数据库中大概有10万多条数据,包括标题、年代、类型、简介、导演、主演、评论数、想看的人数和已经看的人数等等信息,接下来想想能不能对这些数据进行分析获得一些有用的信息。
3