用Python爬取貓眼電影排行榜TOP100

參考資料《Python3網(wǎng)絡(luò)爬蟲開發(fā)實踐》搀擂,作者崔慶才

這篇博客參考了崔慶才的《Python3網(wǎng)絡(luò)爬蟲開發(fā)實踐》有關(guān)部分,記錄了爬取貓眼電影網(wǎng)排名前100的電影信息的過程匈棘。
主要步驟有:

  1. 訪問網(wǎng)站厂捞,獲取頁面源碼
  2. 解析頁面睁本,得到想要的數(shù)據(jù)
  3. 循環(huán)爬取多個頁面
  4. 把數(shù)據(jù)寫入本地文件

1. 分析需要爬取的頁面結(jié)構(gòu)

訪問貓眼電影场靴。觀察頁面啡莉,會看到首頁上有排名前十的電影信息。
找到頁面中的分頁,點擊不同的頁碼票罐。對比不同頁面url的差別,會發(fā)現(xiàn)不同的分頁是以offset參數(shù)作為區(qū)分的泞边。
因為每個頁面都顯示10條電影信息该押,所以offset是以10作為偏移量的。所以第1頁的offset=0阵谚,第2頁的offset=10蚕礼,第3頁的offset=20,后面的頁面也是以此類推梢什。

2. 抓取首頁

2.1 獲取首頁的源碼

首先定義一個方法奠蹬,請求頁面,并獲得頁面源碼:

import requests


def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None


def main():
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    print(html)


main()

在打印結(jié)果中嗡午,可以看到頁面的源碼已經(jīng)返回囤躁。
獲取到的源碼中,有很多的信息不是我們需要的荔睹,這時候狸演,需要把有用的信息提取出來。

2.2 使用正則提取信息

使用谷歌瀏覽器的開發(fā)者工具查看頁面的源代碼僻他,可以發(fā)現(xiàn)我們需要的信息都包含在<dd>標(biāo)簽中宵距。
排名信息包含在class為board-index的i標(biāo)簽中;
片名信息包含在class為name的p標(biāo)簽內(nèi)的a標(biāo)簽中吨拗;
主演姓名包含在class為star的p標(biāo)簽中满哪;
上映日期包含在class為releasetime的p標(biāo)簽中;
評分分別包含在class為integerfraction的i標(biāo)簽中劝篷;
電影封面圖在class為board-img的img的src屬性中哨鸭;
因此,可以寫一個正則表達(dá)式來提取一個電影的上述信息:

<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>

把上面的正則表達(dá)式加入到代碼中:

import requests
import re

def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None


def parse_one_page(html):
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                         + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
                         + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
    items = re.findall(pattern, html)
    print(items)


def main():
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    parse_one_page(html)


main()

輸出結(jié)果如下:


輸出結(jié)果截圖.png

可以看到携龟,上面的輸出結(jié)果可讀性不是很好兔跌,把方法parse_one_page改進(jìn)如下:

def parse_one_page(html):
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                         + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
                         + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
    items = re.findall(pattern, html)
    for item in items:
        yield {
            'index': item[0],
            'image': item[1],
            'title': item[2],
            'actor': item[3].strip()[3:],
            'time': item[4].strip()[5:],
            'score': item[5] + item[6]
        }

至此,單頁的電影信息已經(jīng)獲取完畢峡蟋。
接著將獲取到的信息保存到文本文件中坟桅,以供后續(xù)的使用。

2.3 寫入文件

使用JSON庫的dumps()方法實現(xiàn)字典的序列化蕊蝗,并指定ensure_ascii參數(shù)為false仅乓,這樣可以保證輸出結(jié)果是中文形式,整理代碼如下:

import requests
import re
import json

def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None


def parse_one_page(html):
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                         + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
                         + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
    items = re.findall(pattern, html)
    for item in items:
        yield {
            'index': item[0],
            'image': item[1],
            'title': item[2],
            'actor': item[3].strip()[3:],
            'time': item[4].strip()[5:],
            'score': item[5] + item[6]
        }


def write_to_file(content):
    with open('top100.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False)+'\n')


def main():
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)
        write_to_file(item)


main()

這時候就會發(fā)現(xiàn)本地多了一個名為top100.txt的文件蓬戚,打開查看夸楣,里面存放了首頁排名前10的電影的各個信息。
接下來爬取另外頁面的電影信息。

3. 爬取其余頁面

爬取其余頁面豫喧,只需要對應(yīng)調(diào)整url的offset參數(shù)即可石洗,改寫main方法如下:

def main(offset):
    url = 'http://maoyan.com/board/4?offset=' + str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)
        write_to_file(item)


if __name__ == '__main__':
    for i in range(10):
        main(offset=i*10)
        time.sleep(1)

為了防止過快請求頁面,被封紧显,加入一個延時等待讲衫,最終代碼如下:

import json
import requests
from requests.exceptions import RequestException
import re
import time


def get_one_page(url):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None


def parse_one_page(html):
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                         + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
                         + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
    items = re.findall(pattern, html)
    for item in items:
        yield {
            'index': item[0],
            'image': item[1],
            'title': item[2],
            'actor': item[3].strip()[3:],
            'time': item[4].strip()[5:],
            'score': item[5] + item[6]
        }


def write_to_file(content):
    with open('top100.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False) + '\n')


def main(offset):
    url = 'http://maoyan.com/board/4?offset=' + str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)
        write_to_file(item)


if __name__ == '__main__':
    for i in range(10):
        main(offset=i * 10)
        time.sleep(1)

查看top100.txt,會發(fā)現(xiàn)排名前100名的電影信息已經(jīng)整齊的寫入到了文件中孵班。


完涉兽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市篙程,隨后出現(xiàn)的幾起案子枷畏,更是在濱河造成了極大的恐慌,老刑警劉巖虱饿,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拥诡,死亡現(xiàn)場離奇詭異,居然都是意外死亡郭厌,警方通過查閱死者的電腦和手機袋倔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來折柠,“玉大人宾娜,你說我怎么就攤上這事∩仁郏” “怎么了前塔?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長承冰。 經(jīng)常有香客問我华弓,道長,這世上最難降的妖魔是什么困乒? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任寂屏,我火速辦了婚禮,結(jié)果婚禮上娜搂,老公的妹妹穿的比我還像新娘迁霎。我一直安慰自己,他們只是感情好百宇,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布考廉。 她就那樣靜靜地躺著,像睡著了一般携御。 火紅的嫁衣襯著肌膚如雪昌粤。 梳的紋絲不亂的頭發(fā)上既绕,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音涮坐,去河邊找鬼凄贩。 笑死,一個胖子當(dāng)著我的面吹牛袱讹,可吹牛的內(nèi)容都是我干的怎炊。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼廓译,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了债查?” 一聲冷哼從身側(cè)響起非区,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盹廷,沒想到半個月后征绸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡俄占,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年管怠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缸榄。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡渤弛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出甚带,到底是詐尸還是另有隱情她肯,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布鹰贵,位于F島的核電站晴氨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碉输。R本人自食惡果不足惜籽前,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望敷钾。 院中可真熱鬧枝哄,春花似錦、人聲如沸闰非。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽财松。三九已至瘪贱,卻和暖如春纱控,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背菜秦。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工甜害, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人球昨。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓尔店,卻偏偏與公主長得像,于是被迫代替她去往敵國和親主慰。 傳聞我的和親對象是個殘疾皇子嚣州,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,842評論 25 707
  • 文字/ 愚伯 攝影/秦申 篇一:北方的醪糟 對于米酒,我一向情有獨鐘共螺,追其根源该肴,可能...
    愚伯閱讀 784評論 3 2
  • 今天是離開家鄉(xiāng)的第一天,也是惡運開始的第一天藐不,離開時沒有一個人來送我匀哄,但我并不失落,因為我媽暈車所以最好的還是不要...
    里小木閱讀 167評論 0 0