Python小爬蟲——抓取豆瓣電影Top250資料

來源:互聯網
上載者:User

標籤:圖片   一件事   評價   ade   資源   抓取   https   +=   sina   

寫LeetCode太累了,偶爾練習一下Python,寫個小爬蟲玩一玩~

確定URL格式

先找到豆瓣電影TOP250任意一頁URL地址的格式,如第一頁為:https://movie.douban.com/top250?start=0&filter=,分析該地址:

  • https:// 代表資源傳輸協議使用https協議;
  • movie.douban.com/top250 是豆瓣的次層網域,指向豆瓣伺服器;
  • /top250 是伺服器的某個資源;
  • start=0&filter= 是該URL的兩個參數,分別代表開始位置和過濾條件。

通過分析可以發現,不同頁面之間是有start的值在變化,其他為固定部分。

擷取頁面資料

以物件導向的編碼方式編寫這個程式,養成好的編碼習慣。

基本資料在 \(__init__\) 函數中初始化。注意到其中有一個 \(headers\),這是用來做什麼的呢?有一些網站有一點點反爬蟲機制,對於一般的爬蟲請求拒絕返回實際資料。一般來說,基本的反爬蟲是通過判斷髮送請求中是否有瀏覽器的基本資料,因此,我們可以偽裝成瀏覽器發送這些爬蟲請求,通過修改http包中的heafer實現。

問題又來了,這個User-Agent從哪來呢?你如果急著用,複製我的就可以用!如果想知道自己電腦瀏覽器的基本資料,可以搜尋下載小程式“Fiddler”,開啟程式後,開啟一個網頁,小程式就會擷取發送的請求,其中就包含你要的東西。

class MovieTop(object):    def __init__(self):        self.start = 0        self.param = '&filter'        self.headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) "                                       "AppleWebKit/537.36 (KHTML, like Gecko) "                                       "Chrome/65.0.3325.146 Safari/537.36"}        self.movieList = []        self.filePath = './DoubanTop250.txt'    def get_page(self):        try:            url = 'https://movie.douban.com/top250?start=' + str(self.start) + '&filter='            myRequest = request.Request(url, headers=self.headers)            response = request.urlopen(myRequest)            page = response.read().decode('utf-8')            print('正在擷取第' + str((self.start+25)//25) + '頁資料...')            self.start += 25            return page        except request.URLError as e:            if hasattr(e, 'reason'):                print('擷取失敗,失敗原因:', e.reason)
提取頁面資訊

在上面的代碼中,可以得到頁面的代碼,是HRML格式的文本,我們需要從中提取出有用的資訊。在Chrome瀏覽器中,右鍵查看頁面原始碼可以看到稍微有格式的HTML文本,這和我們擷取的page內容是相同的。找到其中的關鍵資料,如下:

從中可以看到一條記錄的頁面代碼結構,如何從中提取想要的資訊呢?Regex匹配!還記得 \(re模組\) 中的 \(compile\)嗎?

這是比較麻煩的一件事,暫時先這樣寫,懂這行的都知道有一個東西叫做 \(beautiful soup\),它可以簡潔易懂地提取頁面資訊,鑒於練習一下Regex,而且也比較簡單,直接寫出整個匹配式。下面是參考代碼:

還有一個小問題,本來想提取每條記錄的全部資訊,後來發現有的電影沒有“別名”,還有的電影沒有“主演”,不得不忽略這兩條資訊,最後每條記錄只提取了10個資訊。

    def get_page_info(self):        patern = re.compile(u'<div.*?class="item">.*?'                            + u'<div.*?class="pic">.*?'                            + u'<em.*?class="">(.*?)</em>.*?'                            + u'<div.*?class="info">.*?'                            + u'<span.*?class="title">(.*?)</span>.*?'                            + u'<span.*?class="other">(.*?)</span>.*?'                            + u'<div.*?class="bd">.*?'                            + u'<p.*?class="">.*?'                            + u'導演:(.*?)&nbsp;&nbsp;&nbsp;.*?<br>'                            + u'(.*?)&nbsp;/&nbsp;'                            + u'(.*?)&nbsp;/&nbsp;(.*?)</p>.*?'                            + u'<div.*?class="star">.*?'                            + u'<span.*?class="rating_num".*?property="v:average">'                            + u'(.*?)</span>.*?'                            + u'<span>(.*?)人評價</span>.*?'                            + u'<span.*?class="inq">(.*?)</span>'                            , re.S)        while self.start <= 225:            page = self.get_page()            movies = re.findall(patern, page)            for movie in movies:                self.movieList.append([movie[0],                                       movie[1],                                       movie[2].lstrip('&nbsp;/&nbsp;'),                                       movie[3],                                       movie[4].lstrip(),                                       movie[5],                                       movie[6].rstrip(),                                       movie[7],                                       movie[8],                                       movie[9]])
寫入檔案

這個就比較簡單了,直接將其寫入txt即可。

    def write_page(self):        print('開始寫入檔案...')        file = open(self.filePath, 'w', encoding='utf-8')        try:            for movie in self.movieList:                file.write('電影排名:' + movie[0] + '\n')                file.write('電影名稱:' + movie[1] + '\n')                file.write('電影別名:' + movie[2] + '\n')                file.write('導演:' + movie[3] + '\n')                file.write('發行年度:' + movie[4] + '\n')                file.write('製作省/地區:' + movie[5] + '\n')                file.write('電影類別:' + movie[6] + '\n')                file.write('評分:' + movie[7] + '\n')                file.write('參評人數:' + movie[8] + '\n')                file.write('簡短影評:' + movie[9] + '\n')                file.write('\n')            print('成功寫入檔案...')        except Exception as e:            print(e)        finally:            file.close()

完整代碼:https://github.com/Pacsiy/learnPY。

本文著作權歸作者AlvinZH和部落格園所有,歡迎轉載和商用,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利.

Python小爬蟲——抓取豆瓣電影Top250資料

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.