前言
由於之後要做一個實驗,需要用到大量豆瓣使用者的電影資料,因此想到了從豆瓣電影的“看過這部電影 的豆瓣成員”頁面上來獲取較為活躍的豆瓣電影使用者。
連結分析
這是看過”模仿遊戲”的豆瓣成員的網頁連結: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中是這樣的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<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 <span class="allstar40" title="推薦"></span> </p> </td> </tr> </table> |
首先用讀取到的html初始化soup=BeautifulSoup(html)。本次需要的資訊僅僅是使用者id和使用者的電影主頁,因此真正有用的資訊在這段程式碼中:
1 2 3 4 5 6 7 8 9 |
<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就可以得到
1 2 3 |
<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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#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) |