1. 程式人生 > >基於BeautifulSoup爬取豆瓣網上的電影資訊

基於BeautifulSoup爬取豆瓣網上的電影資訊

基於BeautifulSoup實現爬取豆瓣網上的電影資訊

這些天在學習Python,瞭解到用Python做網頁網頁爬蟲非常的方便,於是琢磨著寫了一個簡單的爬蟲程式(感謝萬能的beautifulSoup框架,ps:做網頁解析太方便了)。當然這是計劃中的一部分,說來話長,一開始本來想做一個電影推薦系統(當然和豆瓣的推薦系統不太一樣),傳統的推薦系統是利用基於一種統計的方法,利用觀眾對電影的評分進行統計學處理找到合適的電影推薦個使用者(涉及協作型過濾,蒐集偏好,相似度評價等過程);但是這是一種“大多數說好,就是好的”推薦方法。我想做的是一種主動式的推薦方法:利用對電影的理解(包括電影分格、劇情、演員等要素)對電影本身進行相似度計算,例如一個使用者喜歡看《康熙王朝》,康熙王朝的劇情是講述了一代聖君康熙從登記到歸天所做的豐功偉績,根據對劇情的分析,相類似的還有《漢武大帝》,《成吉思汗》,《雍正王朝》等電視劇,當然豆瓣推薦也能達到這種效果(在豆瓣主頁上輸入一個電影名字以後,出現的網頁下面會有一欄“喜歡這部電影的人也喜歡......”),推薦本質是不一樣的,我設想的方法更多的是對劇情的理解,來找相關的電影,更多涉及的技術難點是對自然語言語義的理解、相似度分析,而不是基於大多數人的“共同愛好”來進行推薦。萬里長城還是得一步一步的走,先爬下來網頁資料才是首要任務。
先說下我的網頁爬蟲實現的功能:可以根據豆瓣網上的不用電影分類進行單獨的爬取,在程式中,我爬取了電影的名字、電影的評分、以及評論該電影的觀眾的數量三個資料,並且可以設定爬取的電影的資料的量(當然理論上是可以無限制的爬取豆瓣上的所有電影)。
**接下來的內容將分兩部分介紹:**
            1. BeautifulSoup簡單介紹
            2. Python爬蟲的實現

一、BeautifulSoup簡潔

簡單來說,BeautifulSoup是python的一個庫,最主要的功能室從網頁上解析資料,官方的解釋如下:
  **Beautiful Soup提供一些簡單的、python式的函式用來處理導航、搜尋、修改分析樹等功能。它是一個工具箱,通過解析文件為使用者提供需要抓取的資料,因為簡單,所以不需要多少程式碼就可以寫出一個完整的應用程式。
Beautiful Soup自動將輸入文件轉換為Unicode編碼,輸出文件轉換為utf-8編碼。你不需要考慮編碼方式,除非文件沒有指定一個編碼方式,這時,Beautiful Soup就不能自動識別編碼方式了。然後,你僅僅需要說明一下原始編碼方式就可以了。
Beautiful Soup已成為和lxml、html6lib一樣出色的python
直譯器,為使用者靈活地提供不同的解析策略或強勁的速度。**
[當然,如果想要系統學習的話,還是去檢視官方文件,寫的特別詳細,而且有詳細的例項,可以快速入門。](https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html)
在我的爬蟲程式中,其實主要用的解析函式只有一個,即find_all()函式,如下例項:
#網頁原始碼:
# <html>
#  <head>
#   <title>
#    The Dormouse's story
#   </title>
#  </head>
# <body> # <p class="title"> # <b> # The Dormouse's story # </b> # </p> # <p class="story"> # Once upon a time there were three little sisters; and their names were # <a class="sister" href="http://example.com/elsie" id="link1"> # Elsie # </a> # , # <a class="sister" href="http://example.com/lacie" id="link2"> # Lacie # </a> # and # <a class="sister" href="http://example.com/tillie" id="link2"> # Tillie # </a> # ; and they lived at the bottom of a well. # </p> # <p class="story"> # ... # </p> # </body> # </html>
上述程式打印出的是網頁的原始碼,很容易看出上述程式碼的特點,<p>和<\p>、<body><\body>、<a>和<\a>等都是成對出現的,這就是HTML程式碼的特點,利用beautifulSoup中的find_all()函式可以分別解析出各個標籤下的內容
soup.find_all('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
只要在find_all()函式的引數中傳入‘a’,那麼就能解析出網頁內容中所有包含<a>和<\a>內容了,而且是以序列的方式返回,是不是覺著非常方便,當然這只是find_all函式的一個簡單用法,還有一個用法就是可以根據屬性值進行查詢,在標籤內部,有些引數是屬於屬性值,例如id="link1"、class="tip-link"等值,find_all函式同樣能勝任查詢具有某個屬性的標籤,例如:
soup.find_all(id='link2')
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
這只是在本文中的爬蟲程式中用到的兩個基本功能,更多關於find_all()函式的妙用請檢視官方文件。。。

二、爬蟲程式的Python實現:

知道了用到的基本技術之後,相信如果對python有一定基礎的,很快就能搞定爬蟲程式了,接下來是整個的原始碼:
#-*— coding:UTF-8 -*-
from bs4 import BeautifulSoup #匯入BeautifulSoup模組
import requests  #匯入requests網頁請求模組
initUrl = 'https://movie.douban.com'   #豆瓣網網址
urls = 'https://movie.douban.com/tag/#!/i!/ckDefault'  #豆瓣網所有電影的分類網址
#獲得電影的分類資訊,以便下一步從分類資訊中分類的爬取網頁
def requreMovieLable(url = urls):
    data = []
    web_data = requests.get(url) #根據網頁連結獲取網頁原始碼
    soup = BeautifulSoup(web_data.text) #網頁預處理
    cataLog = soup.tbody.find_all('a')  #獲取html原始碼中含有<a><\a>標籤中的內容
    for item in cataLog:
        data.append(initUrl + item.get('href'))     #提取<a><\a>標籤中的網頁連結
        # print data
    return data #以列表形式返回各個電影標籤的網頁連結,例如data[0]中包含‘愛情’分類的電影,data[1]中包含‘喜劇’分類的電影,等等
#爬取該網頁的電影名稱、評分、評論人數等資訊
def parsMovie(url = urls):
    web_data = requests.get(url)     #根據網頁連結獲取網頁原始碼
    soup = BeautifulSoup(web_data.text) #網頁預處理
    movieNamePre = soup.find_all(class_="nbg") #尋找網頁原始碼中含有屬性值為‘class_="nbg"’的特定標籤
    movieValueAndNumPre = soup.find_all(class_='star clearfix')  #尋找網頁原始碼中含有屬性值為‘class_='star clearfix'’的特定標籤
    movieValue = []     #儲存電影的評分值
    movieNum = []       #儲存特定電影的評論人數
    for item in movieValueAndNumPre:
        movieValue.append(item.span.next_sibling.next_sibling.text)  #儲存電影的評分
        movieNum.append(item.span.next_sibling.next_sibling.next_sibling.next_sibling.text)    #儲存電影的評論數
    # print movieValueAndNum
    movieName = []   #儲存電影的名字資訊
    for item in movieNamePre:
        movieName.append(item.get('title'))   #解析獲取原始碼中的電影名稱
    u = zip(movieName,movieValue,movieNum)    #將電影名、電影評分、評論人數zip成一個元組
    #輸出解析出的結果資訊
    for name ,val ,num in u:
        print name
        print val
        print num
        print '----' * 10
ul = requreMovieLable(urls)     #獲取主頁面各個電影分類的url地址存取在列表中
page = 3        #設定下載網頁列表的個數
firstUl = ul[0]  #爬取‘愛情’分類下的所有電影
for i in range(0,page):
    print '----------------第%d頁的電影---------------' % i
    parsMovie(firstUl + '?start={}&type=T'.format(str(i*20)))

以下是程式的輸出結果(只截取了部分):
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

初次寫部落格,希望大家批評指正!!