Python爬取豆瓣前250部电影
程序员文章站
2024-02-06 23:38:46
...
爬取豆瓣排名前250的电影
1.准备工作
编写代码之前,安装好以下库:json、request、re、time.
2.爬取分析
需要爬取的目标站点为:https://movie.douban.com/top250?start=0&filter=,打开后可以查看到豆瓣电影的榜单信息。
排名第一的电影是肖申克的救赎,页面显示的信息又影片名称、导演主演、评分、及评论等,将网页滚动到页面最下方直接点击第2页,发现URL发生变化:https://movie.douban.com/top250?start=25&filter=,第二页和第一页的start=的数值不同,因此是一个偏移量的参数,一页显示25部电影。
3. 爬取页面
爬取页面的函数为get_one_page(),主要参数是URL,然后获得页面的html。
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
header的内容可以在检查中查看,如下图所示:
4.正则提取
首先在首页右键点击检查,在Network中的Response查看。
此次爬取的目标是获得排名,影片名称、评分以及评论。因此正则表达式为:
pattern = re.compile('<li>.*?<em class="">(.*?)</em>.*?title.*?>(.*?)</span>.*? <span class="rating_num" property="v:average">(.*?)</span>.*?<span class="inq">(.*?)</span>',re.S)
re.S可以跨行匹配。
之后将提取出的结果生成字典:
for item in items:
yield {'index': item[0],
'title': item[1],
'score': item[2],
'comment':item[3]
}
5.写入文件
将提取出的结果保存至txt文件,使用json库中的dumps()方法实现字典序列化,指定ensure_ascii参数为false,可以保证结果为中文而不是Unicode编码。
def write_to_file(content):
with open('douban250.txt', 'a', encoding='utf-8') as f:
f.write(json.dumps(content, ensure_ascii=False) + '\n')
6.分页爬取
爬取TOP250的电影,需要遍历10个URL,只需要改变offset参数就可以。
url = 'https://movie.douban.com/top250?start='+str(offset)+'&filter='
7.代码整合
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 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('<li>.*?<em class="">(.*?)</em>.*?title.*?>(.*?)</span>.*? <span class="rating_num" property="v:average">(.*?)</span>.*?<span class="inq">(.*?)</span>',re.S)
items = re.findall(pattern, html)
for item in items:
yield {'index': item[0],
'title': item[1],
'score': item[2],
'comment':item[3]
}
def write_to_file(content):
with open('douban250.txt', 'a', encoding='utf-8') as f:
f.write(json.dumps(content, ensure_ascii=False) + '\n')
def main(offset):
url = 'https://movie.douban.com/top250?start='+str(offset)+'&filter='
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 * 25)
time.sleep(1)
8.结果展示
参考
[1] : Python3网络爬虫开发实战