Python爬蟲筆記————抓取 貓眼電影排行榜Top100

注:初學爬蟲,本節僅使用requests庫和使用正則作爲解析工具

 最近學習爬蟲,找個比較簡單的網頁練習了一下,作爲初入爬蟲的小白,不足之處還請大家多多指教。

一、分析url

首先,打開目標站點https://maoyan.com/board/4,打開之後便看到榜單信息:

 排名第一的電影是霸王別姬,頁面中可以看到的信息有電影名稱,主演,上映時間,電影封面,評分,排名等。

頁面最下面有分頁列表,切換到第2頁,看看url發生了哪些變化。

 可以看到第2頁的url爲https://maoyan.com/board/4?offset=10,url與第1頁相比發生了些變化。再分別把第3頁和第4頁的url拿來比較一下。

第1頁:https://maoyan.com/board/4

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

第3頁:https://maoyan.com/board/4?offset=20

第4頁:https://maoyan.com/board/4?offset=30

貌似發現了一些規律,將第1頁改爲https://maoyan.com/board/4?offset=0試試?

發現依然可以找到第1頁,可以發現offset代表了偏移量,如果偏移量爲n,則顯示電影的序號就是n+1--n+10,每頁10條,總共100條,就是10頁,只需分開請求10次,每次的偏移量分別爲0,10,20,30,...,90即可,再得到頁面信息後,使用正則就可以得到電影的排名主演等信息了。

二、獲取第一頁

1、獲取頁面內容,將其封裝成get_one_page()方法,傳入url參數,之後使用main()調用該方法返回網頁內容:

# 請求網頁,返回網頁內容
def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None

def main(offset):
    url = 'https://maoyan.com/board/4?offset=' + str(offset)
    html = get_one_page(url)
    print(html)

2、正則提取

觀察網頁代碼可發現,每條電影信息都由一個dd標籤括起來,二電影的其他信息已經分別標出。

 獲取排名信息的正則表達式:<dd>.*?board-index.*?>(.*?)</i>

再獲取電影封面:<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)"

再提取電影名,主演,上映時間等信息,同樣的道理,最後正則表達式爲:

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

有了正則表達式接下來我們在定義解析頁面的方法,parse_one_page(),傳入參數html

# 使用正則將需要的數據剝離
def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)"'
        +'.*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>'
         +'.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>'
          +'.*?fraction.*?>(.*?)</i>.*?</dd>',
        re.S)
    res = re.findall(pattern, html)
    for i in res:
        yield {
            '排名': i[0],
            '封面': i[1],
            '影片名稱': i[2],
            '主演': i[3].strip()[3:],
            '上映時間': i[4].strip()[5:],
            '評分': i[5].strip() + i[6].strip(),
        }

3、寫入文件

使用json將字典序列化,指定參數ensure_ascii=False,保證寫入的結果是中文。

def write_to_file(content):
    with open('貓眼電影排行TOP100.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False) + '\n')

4、優化main函數,將單頁電影數據寫入到文件。

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

5、分頁爬取

要實現分頁爬取,只需要分別給offset傳入不同的值即可,添加如下調用並修改main函數

def main(offset):
    url = 'https://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)

 

至此我們將貓眼電影的top100已經爬取完了,完整代碼如下:

import requests
import re, json


# 請求網頁,返回響應體
def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 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.*?>(.*?)</i>.*?data-src="(.*?)"'
        +'.*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>'
         +'.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>'
          +'.*?fraction.*?>(.*?)</i>.*?</dd>',
        re.S)
    res = re.findall(pattern, html)
    for i in res:
        yield {
            '排名': i[0],
            '封面': i[1],
            '影片名稱': i[2],
            '主演': i[3].strip()[3:],
            '上映時間': i[4].strip()[5:],
            '評分': i[5].strip() + i[6].strip(),
        }


# 將結果寫入到文件
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 = 'https://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)

 

參考《Python3 網絡爬蟲開發實戰》--崔慶才

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章