[Python從零到壹] 六.網絡爬蟲之BeautifulSoup爬取豆瓣TOP250電影詳解 | 【生長吧!Python】(python從0到1)

      網友投稿 1239 2025-03-31

      https://blog.csdn.net/Eastmount

      https://github.com/eastmountyxz/Python-zero2one

      文章目錄

      一.分析網頁DOM樹結構

      1.分析網頁結構及簡單爬取

      2.定位節點及網頁翻頁分析

      二.爬取豆瓣電影信息

      三.鏈接跳轉分析及詳情頁面爬取

      四.總結

      前文賞析:

      [Python從零到壹] 一.為什么我們要學Python及基礎語法詳解

      [Python從零到壹] 二.語法基礎之條件語句、循環語句和函數

      [Python從零到壹] 三.語法基礎之文件操作、CSV文件讀寫及面向對象

      [Python從零到壹] 四.網絡爬蟲之入門基礎及正則表達式抓取博客案例

      [Python從零到壹] 五.網絡爬蟲之BeautifulSoup基礎語法萬字詳解

      [Python從零到壹] 六.網絡爬蟲之BeautifulSoup爬取豆瓣TOP250電影詳解

      分析網頁DOM樹結構

      爬取豆瓣電影信息列表

      鏈接跳轉分析

      爬取每部電影對應的詳細信息

      本文從實戰出發,讓讀者初步了解分析網頁結構方法并調用BeautifulSoup技術爬取網絡數據,后面章節將進一步深入講解。

      一.分析網頁DOM樹結構

      1.分析網頁結構及簡單爬取

      豆瓣(Douban)是一個社區網站,創立于2005年3月6日。該網站以書影音起家,提供關于書籍、電影、音樂等作品的信息,其作品描述和評論都是由用戶提供(User-Generated Content,簡稱UGC),是Web 2.0網站中具有特色的一個網站。該網站提供了書影音推薦、線下同城活動、小組話題交流等多種服務功能,致力于幫助都市人群發現生活中有用的事物。

      本文主要介紹BeautifulSoup技術爬取豆瓣電影排名前250名的電影信息。第一部分將介紹分析網頁DOM樹結構。爬取豆瓣的地址為:

      https://movie.douban.com/top250?format=text

      上圖中顯示了豆瓣熱門的250部電影的信息,包括電影中文名稱、英文名稱、導演、主演、評分、評價數等信息,接下來需要對其進行DOM樹結構分析。HTML網頁是以標簽對的形式出現,如< html >< /html >、< div >< /div >等,這種標簽對呈樹形結構顯示,通常稱為DOM樹結構。

      在得到一個網頁之后,我們需要結合瀏覽器對其進行元素分析。比如豆瓣電影網站,選中第一部電影《肖申克的救贖》,右鍵鼠標“檢查”(Chrome瀏覽器稱為“檢查”,其他瀏覽器可能稱為“審查元素”等),如下圖2所示。

      顯示結果如圖3所示,可以發現它是在< div class=”article” >< /div >路徑下,由很多個< li >< /li >組成,每一個< li >< /li >分別對應一部電影的信息。其中,電影《肖申克的救贖》HTML中對應內容為:

    1. ......
    2. 通過class值為“item”可以定位電影的信息。調用BeautifulSoup擴展包的find_all(attrs={“class”:“item”}) 函數可以獲取其信息。

      對應的HTML部分代碼如下:

    3. 1 肖申克的救贖
      ...
    4. 下面通過Python3代碼可以獲取電影的信息,調用BeautifulSoup中的find_all()函數獲取< div class=’item’ >的信息,其結果如圖4所示。

      test01.py

      # -*- coding:utf-8 -*- # By:Eastmount CSDN import urllib.request import re from bs4 import BeautifulSoup # 爬蟲函數 def crawl(url, headers): page = urllib.request.Request(url, headers=headers) page = urllib.request.urlopen(page) contents = page.read() #print(contents) soup = BeautifulSoup(contents, "html.parser") print('豆瓣電影250: 序號 \t影片名\t 評分 \t評價人數') for tag in soup.find_all(attrs={"class":"item"}): content = tag.get_text() content = content.replace('\n','') #刪除多余換行 print(content, '\n') # 主函數 if __name__ == '__main__': url = 'http://movie.douban.com/top250?format=text' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \ AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} crawl(url, headers)

      運行結構如圖4所示,爬取了豆瓣Top250的第一頁電影的信息,包括序號、影片名、導演及主演信息、評分、評價人數等。

      注意:urllib.error.HTTPError: HTTP Error 418

      如果直接使用urllib.request.urlopen(url)會提示該錯誤,這是因為爬蟲被攔截,需要模擬瀏覽器訪問,這里可以打開瀏覽器按下F12,找到對應Headers內容,然后在Python代碼中設置User-Agent即可模擬該瀏覽器請求。

      urlopen()函數:

      Python2:urllib2.urlopen(url)

      Python3:urllib.request.urlopen(url)

      urlopen()函數用于創建一個表示遠程url的類文件對象,然后像操作本地文件一樣操作這個類文件對象來獲取遠程數據

      read()函數:

      調用read()讀取網頁內容并賦值給contents變量

      BeautifulSoup函數:

      soup = BeautifulSoup(contents, “html.parser”)

      調用BeautifulSoup解析所抓取網頁源碼的DOM樹結構

      find_all()函數:

      調用BeautifulSoup的find_all()函數獲取屬性class為“item”的所有值,并調用代碼content.replace(’\n’,’’)將換行符替換為空值,從而實現刪除多余換行,最后循環輸出結果。

      2.定位節點及網頁翻頁分析

      通過前一部分我們獲取了電影的簡介信息,但是這些信息是融合在一起的,而在數據分析時,通常需要將某些具有使用價值的信息提取出來,并存儲至數組、列表或數據庫中,比如電影名稱、演員信息、電影評分等特征。

      (1) 文本分析。從獲取的電影簡介文本信息中提取某些特定的值,通常采用字符串處理方法進行提取。

      (2) 節點定位。在寫爬蟲過程中定位相關節點,然后進行爬取所需節點操作,最后賦值給變量或存儲到數據庫中。

      本部分將結合BeautifulSoup技術,采用節點定位方法獲取具體的值。點開HTML網頁,檢查對應的< li >< /li >節點,可以看到該電影的構成情況,再定位節點內容,如< span class=“title” >節點可以獲取標題,< div class=“star” >節點可以獲取電影評分和評價人數。

      獲取節點的核心代碼如下,定位class屬性為“item”的div布局后,再調用find_all()函數查找class屬性為title的標簽,并獲取第一個值輸出,即title[0]。接著調用find()函數爬取評分信息,通過get_text()函數獲取內容。

      for tag in soup.find_all(attrs={"class":"item"}): title = tag.find_all(attrs={"class":"title"}) #電影名稱 info = tag.find(attrs={"class":"star"}).get_text() #爬取評分和評論數 print(title[0]) print(info.replace('\n','')) # 肖申克的救贖 # 9.72279813人評價

      講到這里,我們第一頁的25部電影信息就爬取成功了,而該網頁共10頁,每頁顯示25部電影,如何獲取這250部完整的電影信息呢?這就涉及到鏈接跳轉和網站的翻頁分析。網站的翻頁分析通常有四種方法:

      點擊下一頁分析url網址,分析它們之間的規律,這種方法的網站通常采用GET方法進行傳值,而有的網站采用局部刷新技術,翻頁后的url仍然不變。

      獲取“下一頁”或頁碼的超鏈接,再依次調用urllib2.urlopen(url)函數訪問URL并實現網頁跳轉。

      分析網站Networks提交請求的參數,通過Python設置參數實現翻頁,常用于POST表單。

      采用網頁自動操作技術,獲取下一頁按鈕或超鏈接進行自動點擊跳轉,如selenium技術中的鼠標點擊事件。

      本文主要采用第一種分析方法,后面講述Selenium技術時,會介紹鼠標模擬點擊事件操作的跳轉方法。

      通過點擊圖6中的第2頁、第3頁、第10頁,我們可以看到網頁URL的變化如下。

      第2頁URL:https://movie.douban.com/top250?start=25&filter= 第3頁URL:https://movie.douban.com/top250?start=50&filter= 第10頁URL:https://movie.douban.com/top250?start=225&filter=

      它是存在一定規律的,top250?start=25表示獲取第2頁(序號為26到50號)的電影信息;top250?start=50表示獲取第3頁(序號為51到75號)的電影信息,依次類推,我們寫一個循環即可獲取完整的250部電影信息。核心代碼如下:

      i = 0 while i<10: num = i*25 #每次顯示25部 URL序號按25增加 url = 'https://movie.douban.com/top250?start=' + str(num) + '&filter=' crawl(url) i = i + 1

      注意:當i初始值為0,num值為0,獲取第1頁信息;當i增加為1,num值為25,獲取第2頁信息;當i增加為9,num值為225,獲取第10頁的信息。

      講到這里,爬取豆瓣網電影信息的DOM樹結構分析、網頁鏈接跳轉已經分析完成,下一小節是講解完整的代碼。

      二.爬取豆瓣電影信息

      完整代碼為test02.py文件,如下所示。

      test02.py

      # -*- coding: utf-8 -*- # By:Eastmount CSDN import urllib.request import re from bs4 import BeautifulSoup import codecs #-------------------------------------爬蟲函數------------------------------------- def crawl(url, headers): page = urllib.request.Request(url, headers=headers) page = urllib.request.urlopen(page) contents = page.read() soup = BeautifulSoup(contents, "html.parser") infofile.write("") print('爬取豆瓣電影250: \n') for tag in soup.find_all(attrs={"class":"item"}): #爬取序號 num = tag.find('em').get_text() print(num) infofile.write(num + "\r\n") #電影名稱 name = tag.find_all(attrs={"class":"title"}) zwname = name[0].get_text() print('[中文名稱]', zwname) infofile.write("[中文名稱]" + zwname + "\r\n") #網頁鏈接 url_movie = tag.find(attrs={"class":"hd"}).a urls = url_movie.attrs['href'] print('[網頁鏈接]', urls) infofile.write("[網頁鏈接]" + urls + "\r\n") #爬取評分和評論數 info = tag.find(attrs={"class":"star"}).get_text() info = info.replace('\n',' ') info = info.lstrip() print('[評分評論]', info) #獲取評語 info = tag.find(attrs={"class":"inq"}) if(info): #避免沒有影評調用get_text()報錯 content = info.get_text() print('[影評]', content) infofile.write(u"[影評]" + content + "\r\n") print('') #-------------------------------------主函數------------------------------------- if __name__ == '__main__': #存儲文件 infofile = codecs.open("Result_Douban.txt", 'a', 'utf-8') #消息頭 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \ AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} #翻頁 i = 0 while i<10: print('頁碼', (i+1)) num = i*25 #每次顯示25部 URL序號按25增加 url = 'https://movie.douban.com/top250?start=' + str(num) + '&filter=' crawl(url, headers) infofile.write("\r\n\r\n") i = i + 1 infofile.close()

      運行結果如圖7所示,爬取了電影名稱、網頁連接、評分評論數和影評等信息。

      并且將爬取的250部電影信息存儲到“Result_Douban.txt”文件中,如下圖所示。

      在代碼中,主函數定義循環依次獲取不同頁碼的URL,然后調用crawl(url)函數對每頁的電影信息進行定向爬取。在crawl(url)函數中,通過urlopen()函數訪問豆瓣電影網址,然后調用BeautifulSoup函數進行HTML分析,前面第一部分講解了每部電影都位于< li >< div class=“item” >…< /div >< /li >節點下,故采用如下for循環依次定位到每部電影,然后再進行定向爬取。

      for tag in soup.find_all(attrs={"class":"item"}): #分別爬取每部電影具體的信息

      具體方法如下。

      (1) 獲取序號

      序號對應的HTML源碼如圖8所示,需要定位到< em class >1< /em >節點,通過find(‘em’)函數獲取具體的內容。

      對應的代碼如下:

      num = tag.find('em').get_text() print(num)

      (2) 獲取電影名稱

      電影名稱對應的HTML源碼如圖9所示,包括class='title’對應中文名稱和英文名稱,class='other’對應電影其他名稱。

      對應的代碼如下,因為HTML中包含兩個title,即< span class=‘title’ >< /span >,所以使用下面的函數獲取兩個標題:

      tag.find_all(attrs={“class”:“title”})

      但這里我們僅需要中文標題,則直接通過變量name[0]獲取其第一個值,即為中文名稱,再調用get_text()函數獲取其內容。

      name = tag.find_all(attrs={"class":"title"}) zwname = name[0].get_text() print('[中文名稱]', zwname) infofile.write("[中文名稱]" + zwname + "\r\n")

      同時,上述代碼調用codecs庫進行了文件處理,其中文件操作的核心代碼如下,打開文件三個參數分別是:文件名、讀寫方式、編碼方式,此處文件名為“Result_Douban.txt”,采用文件寫方式(a),編碼方式是utf-8。

      infofile = codecs.open("Result_Douban.txt", 'a', 'utf-8') #打開文件 infofile.write(num+" "+name+"\r\n") #寫文件 infofile.close() #關閉文件

      3.獲取電影鏈接

      電影鏈接對應的HTML源碼如上圖9所示,定位到< div class=‘hd’ >節點下的< a >< /a >節點,然后獲取屬性位href的值,即:attrs[‘href’]。

      url_movie = tag.find(attrs={"class":"hd"}).a urls = url_movie.attrs['href'] print('[網頁鏈接]', urls)

      獲取評分和內容的方法一樣,調用函數即可獲取:

      find(attrs={“class”:“star”}).get_text()

      但是存在一個問題,它輸出的結果將評分數和評價數放在了一起,如“9.4 783221人評價”,而通常在做分析的時候,我們是將評分數存在一個變量中,評價數存在另一變量中。

      這就需要進行簡單的文本處理,這里推薦大家使用前面講述過的正則表達式來處理,將此段代碼修改如下,調用re.compile(r’\d+.?\d*’)獲取字符串中的數字。第一個數字為電影的分數,第二個數字為評論數。

      #爬取評分和評論數 info = tag.find(attrs={"class":"star"}).get_text() info = info.replace('\n',' ') info = info.lstrip() print(info) mode = re.compile(r'\d+\.?\d*') #正則表達式獲取數字 print(mode.findall(info)) i = 0 for n in mode.findall(info): if i==0: print('[分數]', n) infofile.write("[分數]" + n + "\r\n") elif i==1: print('[評論]', n) infofile.write(u"[評論]" + n + "\r\n") i = i + 1

      獲取的結果前后對比如圖10所示。

      三.鏈接跳轉分析及詳情頁面爬取

      https://movie.douban.com/subject/1292052/

      該網頁打開如圖11所示。

      1.爬取詳情頁面基本信息

      下面對詳情頁面進行DOM樹節點分析,其基本信息位于< div class=‘article’ >…< /div >標簽下,核心內容位于該節點下的子節點中,即< div id=‘info’ >…< /div >。使用如下代碼獲取內容:

      info = soup.find(attrs={"id":"info"}) print(info.get_text())

      other = soup.find(attrs={"class":"related-info"}).get_text() print other.replace('\n','').replace(' ','') #過濾空格和換行

      3.爬取詳情頁面電影熱門評論信息

      熱門評論信息位于< div id=‘hot-comments’ >…< /div >節點下,然后獲取節點下的多個class屬性為“comment-item”的div布局,如下圖所示。在使用find()或find_all()函數進行爬取時,需要注意標簽屬性是class還是id,或是其它,必須與之對應一致,才能正確爬取。

      #評論 print('\n評論信息:') for tag in soup.find_all(attrs={"id":"hot-comments"}): for comment in tag.find_all(attrs={"class":"comment-item"}): com = comment.find("p").get_text() #爬取段落p print com.replace('\n','').replace(' ','')

      完整代碼如下:

      test03.py

      # -*- coding: utf-8 -*- # By:Eastmount CSDN import urllib.request import re from bs4 import BeautifulSoup import codecs #-----------------------------------爬取詳細信息------------------------------------- def getInfo(url, headers): page = urllib.request.Request(url, headers=headers) page = urllib.request.urlopen(page) content = page.read() soup = BeautifulSoup(content, "html.parser") #電影簡介 print('電影簡介:') info = soup.find(attrs={"id":"info"}) print(info.get_text()) other = soup.find(attrs={"class":"related-info"}).get_text() print(other.replace('\n','').replace(' ','')) #評論 print('\n評論信息:') for tag in soup.find_all(attrs={"id":"hot-comments"}): for comment in tag.find_all(attrs={"class":"comment-item"}): com = comment.find("p").get_text() print(com.replace('\n','').replace(' ','')) print("\n\n\n----------------------------------------------------------------") #-------------------------------------爬蟲函數------------------------------------- def crawl(url, headers): page = urllib.request.Request(url, headers=headers) page = urllib.request.urlopen(page) contents = page.read() soup = BeautifulSoup(contents, "html.parser") for tag in soup.find_all(attrs={"class":"item"}): #爬取序號 num = tag.find('em').get_text() print(num) #電影名稱 name = tag.find_all(attrs={"class":"title"}) zwname = name[0].get_text() print('[中文名稱]', zwname) #網頁鏈接 url_movie = tag.find(attrs={"class":"hd"}).a urls = url_movie.attrs['href'] print('[網頁鏈接]', urls) #爬取評分和評論數 info = tag.find(attrs={"class":"star"}).get_text() info = info.replace('\n',' ') info = info.lstrip() #正則表達式獲取數字 mode = re.compile(r'\d+\.?\d*') i = 0 for n in mode.findall(info): if i==0: print('[電影分數]', n) elif i==1: print('[電影評論]', n) i = i + 1 #獲取評語 getInfo(urls, headers) #-------------------------------------主函數------------------------------------- if __name__ == '__main__': #消息頭 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \ AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} #翻頁 i = 0 while i<10: print('頁碼', (i+1)) num = i*25 #每次顯示25部 URL序號按25增加 url = 'https://movie.douban.com/top250?start=' + str(num) + '&filter=' crawl(url, headers) i = i + 1

      其中爬取的《龍貓》電影信息輸出如圖16所示。

      講到這里,使用BeautifulSoup技術分析爬取豆瓣電影前250部電影信息的實例已經講解完畢,但在實際爬取過程中可能由于某些頁面不存在會導致爬蟲停止,這時需要使用異常語句“try-except-finally”進行處理。

      同時,爬取過程中需要結合自己所需數據進行定位節點,存儲至本地文件中,也需要結合字符串處理過濾一些多余的空格或換行。

      四.總結

      該系列所有代碼-:

      https://github.com/eastmountyxz/Python-zero2one

      2020年在github的綠瓷磚終于貼完了第一年提交2100余次,獲得1500多+stars,開源93個倉庫,300個粉絲。挺開心的,希望自己能堅持在github打卡五年,督促自己不斷前行。簡單總結下,最滿意的資源是YQ爆發時,去年2月分享的輿情分析和情感分析,用這系列有溫度的代碼為武漢加油;最高贊的是Python圖像識別系列,也獲得了第一位來自國外開發者的貢獻補充;最花時間的是Wannacry逆向系列,花了我兩月逆向分析,幾乎成為了全網最詳細的該蠕蟲分析;還有AI系列、知識圖譜實戰、CVE復現、APT報告等等。當然也存在很多不足之處,希望來年分享更高質量的資源,也希望能將安全和AI頂會論文系列總結進來,真誠的希望它們能幫助到大家,感恩有你,一起加油~

      希望能與大家一起在華為云社區共同承載,原文地址:https://blog.csdn.net/Eastmount/article/details/108887652

      【生長吧!Python】有獎征文火熱進行中:https://bbs.huaweicloud.com/blogs/278897

      (By:娜璋之家 Eastmount 2021-07-07 夜于武漢)

      參考文獻如下:

      北京豆網科技有限公司——豆瓣

      [python爬蟲] BeautifulSoup和Selenium對比爬取豆瓣Top250電影信息 - Eastmount

      Crummy.com網站. BeautifulSoup 4.2.0文檔

      [python知識] 爬蟲知識之BeautifulSoup庫安裝及簡單介紹 - Eastmount

      GitHub Python 網絡

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:安全生產管理人員求職平臺(安全生產管理人員報名網站)
      下一篇:wps中有免費的教學視頻,從哪里找?
      相關文章
      国产亚洲欧洲精品| 在线观看亚洲av每日更新| 亚洲一区AV无码少妇电影☆| 亚洲精品国产自在久久| 亚洲变态另类一区二区三区| 亚洲熟妇久久精品| 伊人久久亚洲综合影院首页| 亚洲欧洲日本在线观看| 亚洲午夜精品国产电影在线观看| 亚洲色图校园春色| 亚洲无砖砖区免费| 亚洲午夜在线一区| 亚洲五月丁香综合视频| 亚洲最大福利视频| 久久亚洲国产最新网站| 亚洲七久久之综合七久久| 亚洲AV永久无码精品一福利 | 色婷婷六月亚洲婷婷丁香| 精品亚洲国产成AV人片传媒| 亚洲综合一区二区精品导航| 久久亚洲AV成人无码软件| 亚洲国产超清无码专区| 亚洲一区二区三区四区视频| 在线观看亚洲AV每日更新无码| 亚洲欧美日韩中文二区| 亚洲AV无码资源在线观看| 亚洲国产一区视频| 久久乐国产精品亚洲综合| 国产AV无码专区亚洲AV毛网站| 亚洲国产精品久久66| 亚洲精品不卡视频| 亚洲乱码在线观看| WWW亚洲色大成网络.COM | 亚洲精品视频在线观看免费 | 亚洲无码精品浪潮| 亚洲精品乱码久久久久久中文字幕 | 亚洲综合色婷婷在线观看| 亚洲av最新在线观看网址| 亚洲一区二区三区在线视频| 亚洲精品亚洲人成在线观看| 久久精品国产亚洲av水果派|