爬取貓眼 TOP100 電影並以 excel 格式儲存
爬取目標
本文將提取貓眼電影 TOP100 排行榜的電影名稱、時間、評分、圖片等資訊,URL 為http://maoyan.com/board/4,提取的結果我們以 excel 格式儲存下來。
準備工作
爬取分析
開啟http://maoyan.com/board/4我們會發現榜單主要顯示 4 個數據:電影名、主演、上映時間和評分。
如圖所示:
網頁下滑到最下方可以發現有分頁的列表,我們點選一下第二頁會發現頁面的 URL 變成了http://maoyan.com/board/4?offset=10,比之前的頁面多了一個 offset=10 的引數,而且頁面顯示的是排行 11-20 名的電影。
由此我們可以總結出規律,offset 代表了一個偏移量值,如果偏移量為 n,則顯示的電影序號就是 n+1 到 n+10,每頁顯示 10 個。所以我們如果想獲取 TOP100 電影,只需要分開請求 10 次,而 10 次的 offset 引數設定為 0,10,20,…,90 即可,這樣我們獲取不同的頁面結果之後再用正則表示式提取出相關資訊就可以得到 TOP100 的所有電影資訊了。
抓取首頁
import requests
def get_one_page(url):
response = requests.get(url)
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()
這樣我們就可以獲取首頁的原始碼了,獲取原始碼之後我們要對頁面進行解析,提取出我們想要的資訊。
使用 BeautifulSoup 進行提取
接下來我們回到網頁看一下頁面的真實原始碼,在開發者工具中 Network 監聽(建議使用谷歌瀏覽器,按 F12 即可檢視網頁資訊),然後檢視一下原始碼。如圖所示:
注意這裡不要在 Elements 選項卡直接檢視原始碼,此處的原始碼可能經過 JavaScript 的操作而和原始請求的不同,我們需要從Network選項卡部分檢視原始請求得到的原始碼。
檢視其中的一條原始碼如圖所示:
可以看到電影名、主演、上映時間和評分分別在屬性 class=”name”、class=”star”、class=”release” 和 class=”score”的文字中
那麼我們可以用 BeautifulSoup 的方法進行提取:
def parse_one_page(html):
soup = bs4.BeautifulSoup(html, 'lxml')
# 獲取電影名
movies = []
targets = soup.find_all(class_='name')
for each in targets:
movies.append(each.get_text())
# 獲取評分
scores = []
targets = soup.find_all(class_='score')
for each in targets:
scores.append(each.get_text())
# 獲取主演資訊
star_message = []
targets = soup.find_all(class_='star')
for each in targets:
star_message.append(each.get_text().split('\n')[1].strip())
print(each.get_text().split('\n')[1].strip())
# 獲取上映時間
play_time = []
targets = soup.find_all(class_='releasetime')
for each in targets:
play_time.append(each.get_text())
result = []
length = len(movies)
for j in range(length):
result.append([movies[j], scores[j], star_message[j], play_time[j]])
return result
這樣我們就成功的將一頁的 10 個電影資訊都提取出來了
寫入檔案
隨後我們將提取的結果做成 excel 表格形式
def save_to_excel(result):
wb = openpyxl.Workbook()
ws = wb.active
ws['A1'] = '電影名稱'
ws['B1'] = '評分'
ws['C1'] = '主演'
ws['D1'] = '上映時間'
for item in result:
ws.append(item)
wb.save('貓眼電影TOP100.xlsx')
分頁爬取
但我們需要爬取的資料是 TOP100 的電影,所以我們還需要遍歷一下給這個連結傳入一個 offset 引數,實現其他 90 部電影的爬取
for i in range(10):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
}
url = 'http://maoyan.com/board/4?offset=' + str(i * 10)
html = get_one_page(url, headers)
result.extend(parse_one_page(html))
整合程式碼
到此為止,我們的貓眼電影 TOP100 的爬蟲就全部完成了,再稍微整理一下,完整的程式碼如下:
import requests
import bs4
from requests.exceptions import RequestException
import openpyxl
def get_one_page(url, headers):
try:
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):
soup = bs4.BeautifulSoup(html, 'lxml')
# 獲取電影名
movies = []
targets = soup.find_all(class_='name')
for each in targets:
movies.append(each.get_text())
# 獲取評分
scores = []
targets = soup.find_all(class_='score')
for each in targets:
scores.append(each.get_text())
# 獲取主演資訊
star_message = []
targets = soup.find_all(class_='star')
for each in targets:
star_message.append(each.get_text().split('\n')[1].strip())
print(each.get_text().split('\n')[1].strip())
# 獲取上映時間
play_time = []
targets = soup.find_all(class_='releasetime')
for each in targets:
play_time.append(each.get_text())
result = []
length = len(movies)
for j in range(length):
result.append([movies[j], scores[j], star_message[j], play_time[j]])
return result
def save_to_excel(result):
wb = openpyxl.Workbook()
ws = wb.active
ws['A1'] = '電影名稱'
ws['B1'] = '評分'
ws['C1'] = '主演'
ws['D1'] = '上映時間'
for item in result:
ws.append(item)
wb.save('貓眼電影TOP100.xlsx')
def main():
result = []
for i in range(10):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
}
url = 'http://maoyan.com/board/4?offset=' + str(i * 10)
html = get_one_page(url, headers)
result.extend(parse_one_page(html))
save_to_excel(result)
if __name__ == '__main__':
main()
執行結果如下圖:
結語
本文參考崔慶才的《Python3 網路爬蟲開發實戰》程式碼部分將正則表示式解析換成 BeautifulSoup 解析。
本程式碼還有改進的地方,比如解析程式碼時有些程式碼重複了,使用的單程序爬取速度較慢,最近 requests 的作者新開發了一個庫 request-html,集網頁獲取與解析與一體,使爬取更簡單。有興趣的可以看看官方文件傳送門。希望大家多多交流。