zoukankan      html  css  js  c++  java
  • [Python]从豆瓣电影批量获取看过这部电影的用户列表

    前言

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

    链接分析

    这是看过"模仿游戏"的豆瓣成员的网页链接: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中是这样的:

      <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和用户的电影主页,因此真正有用的信息在这段代码中:

      <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就可以得到

      <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了。

    完整代码

     1 #coding=utf-8
     2 ##从豆瓣网页中得到用户id
     3 
     4 ##网页地址类型:http://movie.douban.com/subject/26289144/collections?start=0
     5 ##              http://movie.douban.com/subject/26289144/collections?start=20
     6 
     7 from BeautifulSoup import BeautifulSoup
     8 import codecs
     9 import time
    10 import urllib2
    11 
    12 baseUrl='http://movie.douban.com/subject/25895276/collections?start='
    13 
    14 proxyInfo='127.0.0.1:8087'
    15 proxySupport=urllib2.ProxyHandler({'http':proxyInfo})
    16 opener=urllib2.build_opener(proxySupport)
    17 urllib2.install_opener(opener)
    18 
    19 
    20 #将用户信息(id,主页链接)保存至文件
    21 def saveUserInfo(idList,linkList):
    22     if len(idList)!=len(linkList):
    23         print 'Error: len(idList)!=len(linkList) !'
    24         return
    25     writeFile=codecs.open('UserIdList3.txt','a','utf-8')
    26     size=len(idList)
    27     for i in range(size):
    28         writeFile.write(idList[i]+'	'+linkList[i]+'
    ')
    29     writeFile.close()
    30 
    31 #从给定html文本中解析用户id和连接
    32 def parseHtmlUserId(html):
    33     idList=[]   #返回的id列表
    34     linkList=[] #返回的link列表
    35 
    36     soup=BeautifulSoup(html)
    37     ##<td width="80" valign="top">
    38     ##<a href="http://movie.douban.com/people/liaaaar/">
    39     ##<img class="" src="/u3893139-33.jpg" alt="Liar." />
    40     ##</a>
    41     ##</td>
    42     td_tags=soup.findAll('td',width='80',valign='top')
    43     i=0
    44     for td in td_tags:
    45         #前20名用户是看过这部电影的,
    46         #而后面的只是想看这部电影的用户,因此舍弃
    47         if i==20:
    48             break
    49         a=td.a
    50         link=a.get('href')
    51         i_start=link.find('people/')
    52         id=link[i_start+7:-1]
    53         idList.append(id)
    54         linkList.append(link)
    55         i+=1
    56     return (idList,linkList)
    57 
    58 #返回指定编号的网页内容
    59 def getHtml(num):
    60     url=baseUrl+str(num)
    61     page=urllib2.urlopen(url)
    62     html=page.read()
    63     return html
    64 
    65 def launch():
    66     #指定起始编号:20的倍数
    67     ques=raw_input('Start from number?(Multiples of 20) ')
    68     startNum=int(ques)
    69     if startNum%20 != 0:
    70         print 'Input number error!'
    71         return
    72     for i in range(startNum,200,20):
    73         print 'Loading page %d/200 ...' %(i+1)
    74         html=getHtml(i)
    75         (curIdList,curLinkList)=parseHtmlUserId(html)
    76         saveUserInfo(curIdList,curLinkList)
    77         print 'Sleeping.'
    78         time.sleep(5)
  • 相关阅读:
    第四章 方法(4.2 方法的嵌套调用)
    C#利用for循环打印图形练习题
    第三章 C#程序结构 (3.3 循环结构)
    第六章 数组和索引器 (6.6 索引器)
    第五章 类与对象 5.2 猫类(案例二)
    第五章 类与对象 5.1 时间类(案例一)
    第三章 C#程序结构[3.2 选择结构的应用(Windows窗体应用程序)(四)]
    第三章 C#程序结构(3.1 顺序与选择结构)
    第二章 C#语法基础 (2.2 C#语言的运算符和表达式)
    第二章 C#语法基础(2.1C#语言的数据类型二)
  • 原文地址:https://www.cnblogs.com/xiaff/p/4858302.html
Copyright © 2011-2022 走看看