python3爬取豆瓣top250電影


 

需求:爬取豆瓣電影top250的排名、電影名稱、評分、評論人數和一句話影評

環境:python3.6.5


 

准備工作:

豆瓣電影top250(第1頁)網址:https://movie.douban.com/top250?start=0      或者       https://movie.douban.com/top250

每頁展示25個電影,一共10張翻頁

第2頁:https://movie.douban.com/top250?start=25&filter=

第3頁:https://movie.douban.com/top250?start=50&filter=

……

最后一頁:https://movie.douban.com/top250?start=225&filter=

由此可見,除了首頁代碼其他9頁(相對首頁增加了一些字符串)以25遞增

查看每頁的html代碼:

在瀏覽器空白區域點擊“查看源代碼”(不同的瀏覽器可能起的名字不一樣),找到所需要的內容。

快速定位html有效信息的方法:

例如排名第一的電影是《肖申克的救贖》,在html源碼中搜索(ctrl+F)這個名字(不要加書名號),快速定位大致位置,如下圖

 

仔細研究html代碼:

所有影片存放在ol列表中,每一部影片在一個li中,需要提取的信息在不同的標簽中,如下圖所示

代碼邏輯為:查找ol→li→各個標簽

 

需要用到的第三方庫:

from bs4 import BeautifulSoup as bs
from urllib import request

 

讀取html源碼(以首頁為例)

1     h="https://movie.douban.com/top250"
2     resp = request.urlopen(h)
3     html_data = resp.read().decode('utf-8')
4     soup = bs(html_data,'lxml')
5     #print(soup.prettify())

第5行的soup.prettify()輸出的比較好看,但是有可能更改一些並列標簽的前后位置,用這個輸出只是看起來更人性化一些

 

查找ol標簽,獲取本頁面上25部電影

通過class名稱,因為這個class是唯一命名的,因此無需find_all,只需要find(這個是查找第一個)

1     movieList = soup.find('ol',attrs={'class':"grid_view"})

 

在ol內查找li標簽,無class和id,只需標簽名即可

1 movie = movieList.find_all('li')#獲取每一個li(每個li是一個電影),以數組方式

返回結果是一位數組,每個元素是li標簽

 

在每一個li標簽內提取有用信息

1     for i in range(0,25):
2         name = movie[i].find('span',class_="title").string#獲得影片名稱
3         score = movie[i].find('span',class_="rating_num").string#獲得影片評分
4         num = movie[i].find('div',class_="star").find_all('span')[-1].string.strip('人評價')#獲得影片評價人數
5         quote = movie[i].find('span',class_="inq")#獲得影片短評

.string和get_text()在本代碼中顯示結果一樣(有些代碼中返回顯示也是不同的),但是返回類型不同

注意第4行獲取評價人數時,span標簽內無class和id等,只能先把div中所有的信息提取(返回結果是一位數組),人數在數組中最后一個,通過數組方法[-1]提取這個標簽,通過string提取標簽內內容,再用strip字符串方法去掉“人評價”這幾個字

還有一點需要注意是,有幾部影片是沒有短評的(通過運行程序的結果才能看到,返回的是None),如果需要顯示的更加人性化一些,添加以下語句:

1         if quote is None:
2             quote = "暫無"
3         else:
4             quote = quote.string

 

查找所有信息:不要想着把10頁的html先拼接成一個html處理,這樣的的html進行soup時只能提取到第一個<html>標簽內的,也就是說只能查到第一頁的信息。因此總體思路還是遍歷每一頁的電影信息,然后將結果拼接成數組。如果只是print出來或者逐行寫入歧途文件的話無需整合所有影片

 

寫入txt文件,提取出的結果是二維數組

1 #將數組movieData250寫入文件txt
2 import codecs
3 s ="—————————豆瓣電影top250——————————\r\n"
4 f = codecs.open("豆瓣電影top250.txt",'w','utf-8')
5 f.write(s)
6 
7 for i in movieData250:
8     f.write(str(i)+'\r\n')  #\r\n為換行符
9 f.close()

 

源代碼:

 1 #豆瓣電影前250信息,寫入txt文件
 2 
 3 from bs4 import BeautifulSoup as bs
 4 from urllib import request
 5 k = 0
 6 n = 1
 7 movieData250 = []
 8 
 9 #讀取每一個網頁25個電影信息
10 def info25():
11     movieData = []
12     for i in range(0,25):
13         name = movie[i].find('span',class_="title").string#獲得影片名稱
14         score = movie[i].find('span',class_="rating_num").string#獲得影片評分
15         num = movie[i].find('div',class_="star").find_all('span')[-1].string.strip('人評價')#獲得影片評價人數
16         quote = movie[i].find('span',class_="inq")#獲得影片短評
17         if quote is None:
18             quote = "暫無"
19         else:
20             quote = quote.string
21         #movieData[i] = [i+1,name,score,num,quote]
22         movieData.append([i+1+k,name,score,num,quote])
23     #print(movieData)
24     return movieData
25     #movieData250 = movieData250 + movieData
26 
27 
28 
29 while(k == 0):
30     h="https://movie.douban.com/top250"
31     resp = request.urlopen(h)
32     html_data = resp.read().decode('utf-8')
33     soup = bs(html_data,'lxml')
34     #print(soup.prettify())
35     #movieList=soup.find('ol')#尋找第一個ol標簽,得到所有電影
36     #movieList=soup.find('ol',class_="grid_view")#以下兩種方法均可
37     movieList = soup.find('ol',attrs={'class':"grid_view"})
38     movie = movieList.find_all('li')#獲取每一個li(每個li是一個電影),以數組方式
39     movieData250 +=info25()
40     k += 25
41 
42 while(k<250):
43 
44     h = "https://movie.douban.com/top250?start=" + str(k) + "&filter="
45     resp=request.urlopen(h)
46     html_data=resp.read().decode('utf-8')
47     soup=bs(html_data,'lxml')
48     #print(soup.prettify())
49     #movieList=soup.find('ol')#尋找第一個ol標簽,得到所有電影
50     #movieList=soup.find('ol',class_="grid_view")#以下兩種方法均可
51     movieList=soup.find('ol',attrs={'class':"grid_view"})
52     movie=movieList.find_all('li')#獲取每一個li(每個li是一個電影),以數組方式
53     movieData250 += info25()
54     k+=25
55 
56 print(movieData250)
57 
58 
59 #將數組movieData250寫入文件txt
60 import codecs
61 s ="—————————豆瓣電影top250——————————\r\n"
62 f = codecs.open("豆瓣電影top250.txt",'w','utf-8')
63 f.write(s)
64 
65 for i in movieData250:
66     f.write(str(i)+'\r\n')  #\r\n為換行符
67 f.close()

輸出的txt:

顯示結果不是很友好~~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM