抓取貓眼電影上面Top100榜單,抓取的內容有電影名稱,主演,上映時間,圖片,得分等信息。抓取的內容以文件形式保存,地址為https://maoyan.com/board/4
1.分析
該榜單頁面如下
拉到底部點擊下一頁,發現此時的URL變化了。
此時的URL變為https://maoyan.com/board/4?offset=10,比之前的URL多了參數offset=10,再點擊下一頁的URL為https://maoyan.com/board/4?offset=20,由此我們發現了規律,Top100,每頁展示10部電影,這樣100部電影需要請求10次
2.抓取首頁
首先來抓取第一頁的內容,我們編寫一個get_one_page()的方法
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()
3.正則提取
網頁在開發者模式下,network,查看源碼
排名第一的霸王別姬的源碼如下:
1
9.
5
可以看到一部電影對應一個
dd
節點,排名信息在
class
為
board-index
的
i
節點內,利用非貪婪匹配來提取
i
節點內的信息,正則表達式為
.*?board-index.*?>(.*?)
然后提取圖片信息,接下來的
a
節點,里面有兩個
img
節點,經過檢查后發現,第二個
img
節點的
data-src
屬性是圖片的鏈接。于是提取第二個
img
節點的
data-src
屬性,正則表達式改寫如下:
.*?board-index.*?>(.*?).*?data-src="(.*?)"
之后,提取電影名稱,在后面的
p
節點內,
class
為
name
,之后的
a
節點里
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?)
主演信息在
p
節點下
class
為
star
,上映時間在
p
節點下
class
為
releasetime
,評分在‘p’節點下的’class’為
score
,其中整數部分對應
integer
,小數部分對應為
fraction
。完整的表達式為
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)
.*?releasetime.*?>(.*?)
.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
這樣就可以將一頁中10部電影的信息提取出來
定義解析頁面的方法為
parse_one_page()
,主要通過正則表達式提取想要的內容
def parse_one_page(html):
pattern = re.compile( '
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)
.*?releasetime.*?>(.*?)
.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
',
re.S)
items = re.findall(pattern,html)
print(items)
提取出來的結果如下:
[('1', 'https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c', '霸王別姬', '\n 主演:張國榮,張豐毅,鞏俐\n ', '上映時間:1993-01-01', '9.', '5'), ('2', 'https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c', '肖申克的救贖', '\n 主演:蒂姆·羅賓斯,摩根·弗里曼,鮑勃·岡頓\n ', '上映時間:1994-09-10(加拿大)', '9.', '5'), ('3', 'https://p0.meituan.net/movie/289f98ceaa8a0ae737d3dc01cd05ab052213631.jpg@160w_220h_1e_1c', '羅馬假日', '\n 主演:格利高里·派克,奧黛麗·赫本,埃迪·艾伯特\n ', '上映時間:1953-09-02(美國)', '9.', '1'), ('4', 'https://p1.meituan.net/movie/6bea9af4524dfbd0b668eaa7e187c3df767253.jpg@160w_220h_1e_1c', '這個殺手不太冷', '\n 主演:讓·雷諾,加里·奧德曼,娜塔莉·波特曼\n ', '上映時間:1994-09-14(法國)', '9.', '5'), ('5', 'https://p1.meituan.net/movie/b607fba7513e7f15eab170aac1e1400d878112.jpg@160w_220h_1e_1c', '泰坦尼克號', '\n 主演:萊昂納多·迪卡普里奧,凱特·溫絲萊特,比利·贊恩\n ', '上映時間:1998-04-03', '9.', '5'), ('6', 'https://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@160w_220h_1e_1c', '唐伯虎點秋香', '\n 主演:周星馳,鞏俐,鄭佩佩\n ', '上映時間:1993-07-01(中國香港)', '9.', '1'), ('7', 'https://p0.meituan.net/movie/46c29a8b8d8424bdda7715e6fd779c66235684.jpg@160w_220h_1e_1c', '魂斷藍橋', '\n 主演:費雯·麗,羅伯特·泰勒,露塞爾·沃特森\n ', '上映時間:1940-05-17(美國)', '9.', '2'), ('8', 'https://p0.meituan.net/movie/223c3e186db3ab4ea3bb14508c709400427933.jpg@160w_220h_1e_1c', '亂世佳人', '\n 主演:費雯·麗,克拉克·蓋博,奧利維婭·德哈維蘭\n ', '上映時間:1939-12-15(美國)', '9.', '1'), ('9', 'https://p1.meituan.net/movie/ba1ed511668402605ed369350ab779d6319397.jpg@160w_220h_1e_1c', '天空之城', '\n 主演:寺田農,鷲尾真知子,龜山助清\n ', '上映時間:1992', '9.', '1'), ('10', 'https://p0.meituan.net/movie/b0d986a8bf89278afbb19f6abaef70f31206570.jpg@160w_220h_1e_1c', '辛德勒的名單', '\n 主演:連姆·尼森,拉爾夫·費因斯,本·金斯利\n ', '上映時間:1993-12-15(美國)', '9.', '2')]
我們處理一下結果,讓它以字典的形式呈現:
def parse_one_page(html):
pattern = re.compile( '
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)
.*?releasetime.*?>(.*?)
.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
',
re.S)
items = re.findall(pattern,html)
for item in items:
yield{
'排名':item[0],
'圖片':item[1],
'電影名稱':item[2],
'演員':item[3].strip()[3:],
'上映時間':item[4].strip()[5:],
'評分':item[5]+item[6]}
運行結果如下:
{'排名': '1', '圖片': 'https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c', '電影名稱': '霸王別姬', '演員': '張國榮,張豐毅,鞏俐', '上映時間': '1993-01-01', '評分': '9.5'}
{'排名': '2', '圖片': 'https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c', '電影名稱': '肖申克的救贖', '演員': '蒂姆·羅賓斯,摩根·弗里曼,鮑勃·岡頓', '上映時間': '1994-09-10(加拿大)', '評分': '9.5'}
{'排名': '3', '圖片': 'https://p0.meituan.net/movie/289f98ceaa8a0ae737d3dc01cd05ab052213631.jpg@160w_220h_1e_1c', '電影名稱': '羅馬假日', '演員': '格利高里·派克,奧黛麗·赫本,埃迪·艾伯特', '上映時間': '1953-09-02(美國)', '評分': '9.1'}
{'排名': '4', '圖片': 'https://p1.meituan.net/movie/6bea9af4524dfbd0b668eaa7e187c3df767253.jpg@160w_220h_1e_1c', '電影名稱': '這個殺手不太冷', '演員': '讓·雷諾,加里·奧德曼,娜塔莉·波特曼', '上映時間': '1994-09-14(法國)', '評分': '9.5'}
{'排名': '5', '圖片': 'https://p1.meituan.net/movie/b607fba7513e7f15eab170aac1e1400d878112.jpg@160w_220h_1e_1c', '電影名稱': '泰坦尼克號', '演員': '萊昂納多·迪卡普里奧,凱特·溫絲萊特,比利·贊恩', '上映時間': '1998-04-03', '評分': '9.5'}
{'排名': '6', '圖片': 'https://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@160w_220h_1e_1c', '電影名稱': '唐伯虎點秋香', '演員': '周星馳,鞏俐,鄭佩佩', '上映時間': '1993-07-01(中國香港)', '評分': '9.1'}
{'排名': '7', '圖片': 'https://p0.meituan.net/movie/46c29a8b8d8424bdda7715e6fd779c66235684.jpg@160w_220h_1e_1c', '電影名稱': '魂斷藍橋', '演員': '費雯·麗,羅伯特·泰勒,露塞爾·沃特森', '上映時間': '1940-05-17(美國)', '評分': '9.2'}
{'排名': '8', '圖片': 'https://p0.meituan.net/movie/223c3e186db3ab4ea3bb14508c709400427933.jpg@160w_220h_1e_1c', '電影名稱': '亂世佳人', '演員': '費雯·麗,克拉克·蓋博,奧利維婭·德哈維蘭', '上映時間': '1939-12-15(美國)', '評分': '9.1'}
{'排名': '9', '圖片': 'https://p1.meituan.net/movie/ba1ed511668402605ed369350ab779d6319397.jpg@160w_220h_1e_1c', '電影名稱': '天空之城', '演員': '寺田農,鷲尾真知子,龜山助清', '上映時間': '1992', '評分': '9.1'}
{'排名': '10', '圖片': 'https://p0.meituan.net/movie/b0d986a8bf89278afbb19f6abaef70f31206570.jpg@160w_220h_1e_1c', '電影名稱': '辛德勒的名單', '演員': '連姆·尼森,拉爾夫·費因斯,本·金斯利', '上映時間': '1993-12-15(美國)', '評分': '9.2'}
4.寫入網頁
我們將提取的結果寫入文件,這里直接寫入到一個文本文件中。這里通過
JSON庫
的
dumps()
方法實現字典的序列化,并指定
ensure_ascii
參數為
False
,這樣可以保證輸出結果是中文形式而不是
Unicode
編碼。代碼如下:
def write_to_json(content):
with open('result.txt','a') as f:
print(type(json.dumps(content)))
f.write(json.dumps(content,ensure_ascii=False)+'\n')
content
為提取下來的一部電影的信息
5.整合代碼
def main():
url = 'http://maoyan.com/board/4'
html = get_one_page(url)
for item in parse_one_page(html):
print(item)
write_to_json(item)
實現了將第一頁的十部電影爬取下來,保存到本地文件中。
6.分頁爬取
我們想要爬取的是前100部電影,所以還需要遍歷一下,給這個鏈接傳入offset參數,實現其他90部電影的爬取
if __name__ == '__main__':
for i in range(10):
main(offset=i * 10)
那么在定義
main()
時需要給它一個
offset
參數
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_json(item)
完整代碼
import requests
import re
import json
def get_one_page(url):
response = requests.get(url)
if response.status_code == 200:
return response.text
return None
def parse_one_page(html):
pattern = re.compile( '
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)
.*?releasetime.*?>(.*?)
.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
',
re.S)
items = re.findall(pattern,html)
for item in items:
yield{
'排名':item[0],
'圖片':item[1],
'電影名稱':item[2],
'演員':item[3].strip()[3:],
'上映時間':item[4].strip()[5:],
'評分':item[5]+item[6]}
def write_to_json(content):
with open('result.txt','a') as f:
print(type(json.dumps(content)))
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_json(item)
if __name__ == '__main__':
for i in range(10):
main(offset=i * 10)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
