天天看點

爬蟲簡單入門實戰項目:用正規表達式爬取貓眼電影排行

  今天學習了《python3網絡爬蟲開發實戰》的正規表達式部分,緊接着是一個爬蟲小項目:爬取貓眼電影排行,看着沒什麼難度,就想自己來獨立完成這個項目,部分參考了書上的代碼。

項目目标

利用正規表達式抓取貓眼電影TOP100電影資訊并儲存。

用到的庫

requests庫、re庫

初步分析

貓眼電影TOP100 的連結位址是

https://maoyan.com/board/4

,打開以後是這樣的:

爬蟲簡單入門實戰項目:用正規表達式爬取貓眼電影排行

把它拉到最下方,是有分頁的,點選第二頁:

爬蟲簡單入門實戰項目:用正規表達式爬取貓眼電影排行

我們可以看到頁面的URL變成了

https://maoyan.com/board/4?offset=10

,由此可以推測出改變offset就可以改變頁面顯示的電影(讀者可以自行在URL上任意修改數字),offset=n的時候,頁面顯示排名第n~n+10的電影,是以,我們通過改變offset的值可以抓取所有的頁面。

擷取單頁

首先要擷取到頁面,這裡使用requests庫。

import requests as req
def get_one_page(url):
    #設定headers僞造浏覽器資訊
    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"}
    #擷取頁面
    response = req.get(url, headers=headers)
    #狀态碼200代表成功
    if 200 == response.status_code:
        return response.text
    return None
           

構造分析器

首先我們要檢視網頁的源代碼(Ctrl+U):

爬蟲簡單入門實戰項目:用正規表達式爬取貓眼電影排行

可以看到:一部電影的資訊是夾在

<dd>....</dd>

标簽中間的,同理,我們可以找到電影的名稱、主演、上映時間等資訊。

接下來要構造函數來分析這個頁面,用到了re庫。

import re
def parse_one_page(html):
    #找到所有的電影
    films = re.findall('<dd>.*?</dd>', html, re.S)
    films_info = []
    for film in films:
        film_info = {}
        #利用正規表達式擷取電影的各種資訊
        ranking = re.search('<i class="board-index.*?>(\d+)</i>', film, re.S)
        name = re.search(' <p class="name">.*?title="(.*?)" .*?', film, re.S)
        star = re.search('<p class="star">\s+(.*?)\s+</p>', film, re.S)
        time = re.search('<p class="releasetime">(.*?)</p>', film, re.S)
        film_info['ranking'] = ranking.group(1)
        film_info['name'] = name.group(1)
        film_info['star'] = star.group(1)
        film_info['time'] = time.group(1)
        films_info.append(film_info)
    return films_info
           

到這裡,我們就已經把一頁的電影資訊找出來了。

爬取所有頁

接下來要把所有頁都爬下來:

def main():
    link = 'https://maoyan.com/board/4?offset='
    for i in range(0, 91, 10):
        url = link+str(i)
        html = get_one_page(url)
        parse_one_page(html)
           

儲存結果

在這裡我寫了一個小函數來實作儲存的功能:

def save(content):
    with open('maoyan.txt', 'a', encoding='utf-8') as f:
        f.write(content)
           

然後我在

parse_one_page(html)

函數裡對每個電影資訊進行了儲存:

def parse_one_page(html):
    films = re.findall('<dd>.*?</dd>', html, re.S)
    films_info = []
    for film in films:
        film_info = {}
        ranking = re.search('<i class="board-index.*?>(\d+)</i>', film, re.S)
        name = re.search(' <p class="name">.*?title="(.*?)" .*?', film, re.S)
        star = re.search('<p class="star">\s+(.*?)\s+</p>', film, re.S)
        time = re.search('<p class="releasetime">(.*?)</p>', film, re.S)
        film_info['ranking'] = ranking.group(1)
        film_info['name'] = name.group(1)
        film_info['star'] = star.group(1)
        film_info['time'] = time.group(1)
        films_info.append(film_info)
        save(str(film_info)+'\n')
    return films_info
           

結果展示

我最終的内容如圖所示:

爬蟲簡單入門實戰項目:用正規表達式爬取貓眼電影排行

代碼整合

整個項目所有代碼如下:

import requests as req
import re
def get_one_page(url):
    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"}
    response = req.get(url, headers=headers)
    if 200 == response.status_code:
        return response.text
    return None

def parse_one_page(html):
    films = re.findall('<dd>.*?</dd>', html, re.S)
    films_info = []
    for film in films:
        film_info = {}
        ranking = re.search('<i class="board-index.*?>(\d+)</i>', film, re.S)
        name = re.search(' <p class="name">.*?title="(.*?)" .*?', film, re.S)
        star = re.search('<p class="star">\s+(.*?)\s+</p>', film, re.S)
        time = re.search('<p class="releasetime">(.*?)</p>', film, re.S)
        film_info['ranking'] = ranking.group(1)
        film_info['name'] = name.group(1)
        film_info['star'] = star.group(1)
        film_info['time'] = time.group(1)
        films_info.append(film_info)
        save(str(film_info)+'\n')
    return films_info

def save(content):
    with open('maoyan.txt', 'a', encoding='utf-8') as f:
        f.write(content)
def main():
    link = 'https://maoyan.com/board/4?offset='
    for i in range(0, 91, 10):
        url = link+str(i)
        html = get_one_page(url)
        parse_one_page(html)

if __name__ == '__main__':
    main()

           

小結

這個項目是對靜态頁面的解析,相對簡單,适合入門,用正規表達式來解析頁面是一種比較不友善的方法,但也是一種必備技能,還可以用BeautifulSoup、Xpath等來進行頁面解析,更加靈活友善,功能也更加強大。為了簡便起見,本文的代碼還有很多不足之處,比如沒有設定休息時間,這在有一定反爬技術的網站上是行不通的;還比如沒有注意中文的編碼問題,有可能在其它網站上面爬下來的中文就是亂碼等等。

相關連結

《python3網絡爬蟲開發實戰》項目源碼