从豆瓣电影批量获取看过这部电影的用户列表,豆瓣用户列表, 链接分析 这是看过模仿


前言

由于之后要做一个实验,需要用到大量豆瓣用户的电影数据,因此想到了从豆瓣电影的“看过这部电影 的豆瓣成员”页面上来获取较为活跃的豆瓣电影用户。

链接分析

这是看过”模仿游戏”的豆瓣成员的网页链接:http://movie.douban.com/subject/10463953/collections。

一页上显示了20名看过这部电影的豆瓣用户。当点击下一页时,当前连接变为:http://movie.douban.com/subject/10463953/collections?start=20。

由此可知,当请求下一页内容时,实际上就是将”start”后的索引增加20。

因此,我们可以设定base_url=’http://movie.douban.com/subject/10463953/collections?start=’,i=range(0,200,20),在循环中url=base_url+str(i)。

之所以要把i的最大值设为180,是因为后来经过测试,豆瓣只给出看过一部电影的最近200个用户。

读取网页

在访问时我设置了一个HTTP代理,并且为了防止访问频率过快而被豆瓣封ip,每读取一个网页后都会调用time.sleep(5)等待5秒。 在程序运行的时候干别的事情好了。

网页解析

本次使用BeautifulSoup库解析html。

每一个用户信息在html中是这样的:

Python
 <table width="100%" class="">
  <tr>
      <td width="80" valign="top">
          <a href="http://movie.douban.com/people/46770381/">
              <img class="" src="http://img4.douban.com/icon/u46770381-16.jpg" alt="七月" />
          </a>
      </td>
      <td valign="top">
          <div class="pl2">
              <a href="http://movie.douban.com/people/46770381/" class="">七月
                  <span style="font-size:12px;">(银川)</span>
              </a>
          </div>
          <p class="pl">2015-08-23
                  &nbsp;<span class="allstar40" title="推荐"></span>
          </p>
      </td>
  </tr>
  </table>

首先用读取到的html初始化soup=BeautifulSoup(html)。本次需要的信息仅仅是用户id和用户的电影主页,因此真正有用的信息在这段代码中:

Python
 <td width="80" valign="top">
      <a href="http://movie.douban.com/people/46770381/">
          <img class="" src="http://img4.douban.com/icon/u46770381-16.jpg" alt="七月" />
      </a>
  </td> <td width="80" valign="top">
      <a href="http://movie.douban.com/people/46770381/">
          <img class="" src="http://img4.douban.com/icon/u46770381-16.jpg" alt="七月" />
      </a>
  </td>

因此在Python代码中通过td_tags=soup.findAll(‘td’,width=’80’,valign=’top’)找到所有<td width=”80″ valign=”top”>的块。

td=td_tags[0],a=td.a就可以得到

Python
<a href="http://movie.douban.com/people/46770381/">
      <img class="" src="http://img4.douban.com/icon/u46770381-16.jpg" alt="七月" />
  </a>

通过link=a.get(‘href’)可以得到href属性,也就用户的电影主页链接。然后通过字符串查找也就可以得到用户ID了。

完整代码

Python
#coding=utf-8
##从豆瓣网页中得到用户id

##网页地址类型:http://movie.douban.com/subject/26289144/collections?start=0
##              http://movie.douban.com/subject/26289144/collections?start=20

from BeautifulSoup import BeautifulSoup
import codecs
import time
import urllib2

baseUrl='http://movie.douban.com/subject/25895276/collections?start='

proxyInfo='127.0.0.1:8087'
proxySupport=urllib2.ProxyHandler({'http':proxyInfo})
opener=urllib2.build_opener(proxySupport)
urllib2.install_opener(opener)

#将用户信息(id,主页链接)保存至文件
def saveUserInfo(idList,linkList):
    if len(idList)!=len(linkList):
        print 'Error: len(idList)!=len(linkList) !'
        return
    writeFile=codecs.open('UserIdList3.txt','a','utf-8')
    size=len(idList)
    for i in range(size):
        writeFile.write(idList[i]+'\t'+linkList[i]+'\n')
    writeFile.close()

#从给定html文本中解析用户id和连接
def parseHtmlUserId(html):
    idList=[]   #返回的id列表
    linkList=[] #返回的link列表

    soup=BeautifulSoup(html)
    ##<td width="80" valign="top">
    ##<a href="http://movie.douban.com/people/liaaaar/">
    ##<img class="" src="/u3893139-33.jpg" alt="Liar." />
    ##</a>
    ##</td>
    td_tags=soup.findAll('td',width='80',valign='top')
    i=0
    for td in td_tags:
        #前20名用户是看过这部电影的,
        #而后面的只是想看这部电影的用户,因此舍弃
        if i==20:
            break
        a=td.a
        link=a.get('href')
        i_start=link.find('people/')
        id=link[i_start+7:-1]
        idList.append(id)
        linkList.append(link)
        i+=1
    return (idList,linkList)

#返回指定编号的网页内容
def getHtml(num):
    url=baseUrl+str(num)
    page=urllib2.urlopen(url)
    html=page.read()
    return html

def launch():
    #指定起始编号:20的倍数
    ques=raw_input('Start from number?(Multiples of 20) ')
    startNum=int(ques)
    if startNum%20 != 0:
        print 'Input number error!'
        return
    for i in range(startNum,200,20):
        print 'Loading page %d/200 ...' %(i+1)
        html=getHtml(i)
        (curIdList,curLinkList)=parseHtmlUserId(html)
        saveUserInfo(curIdList,curLinkList)
        print 'Sleeping.'
        time.sleep(5)

评论关闭