思路
頁面總共有250部電影,網站分爲10頁進行展示,通過分析發現,每個頁面的URL存在如下規律:
第一頁:
https://movie.douban.com/top250?start=0
第二頁:
https://movie.douban.com/top250?start=25
第三頁:
https://movie.douban.com/top250?start=50
……
最後一頁:
https://movie.douban.com/top250?start=225
相信聰明的你,已經發現規律了吧!相鄰兩個頁面的URL中的start參數之差爲25,因此,我們可以根據這個規律來構造每一個頁面的URL,通過循環來爬取每一個頁面。
對於頁面中,數據信息的提取,這裏主要運用了XPath。如果對此語法不熟悉的小夥伴,可以參考我以前的博文。
傳送門 ——> 網絡爬蟲之數據解析
更多有關爬蟲的知識,也可以閱讀我的爬蟲專欄。
代碼
import requests
import re
import json
import os
from lxml import etree
"""
爬取豆瓣電影Top250
"""
url = 'https://movie.douban.com/top250?start='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
data = []
def main():
number = [i for i in range(0, 230, 25)]
for i in number:
page_url = url + str(i)
r = requests.get(page_url, headers=headers)
parse_data(r.text)
save_data()
def parse_data(text):
html = etree.HTML(text)
li_list = html.xpath('//ol[@class="grid_view"]/li')
for li in li_list:
url = ''.join(li.xpath('./div/div[@class="pic"]/a/@href'))
pic = ''.join(li.xpath('./div/div[@class="pic"]/a/img/@src'))
title = ''.join(li.xpath('./div/div[@class="info"]/div[@class="hd"]/a/span[1]/text()'))
rating_num = ''.join(li.xpath('./div/div[@class="info"]/div[@class="bd"]/div/span[2]/text()'))
comment_num = ''.join(li.xpath('./div/div[@class="info"]/div[@class="bd"]/div/span[last()]/text()'))
info = ''.join(li.xpath('./div/div[@class="info"]/div[@class="bd"]/p/text()'))
info = re.sub(r'\s', '', info)
film = {
'title': title,
'url': url,
'pic': pic,
'rating_num': rating_num,
'commment_num': comment_num,
'info': info
}
print(film)
data.append(film)
def save_data():
if not os.path.exists('./result/'):
os.makedirs('./result/')
with open('./result/doubanTop250.json', 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
if __name__ == '__main__':
main()