
去年,我在做一个小实验:想抓取几部经典电影的豆瓣影评,看看不同年份观众的评价差异。刚开始觉得没什么难度,不就是循环翻页、解析HTML吗?
结果一上手,才发现里面暗藏玄机。
https://movie.douban.com/subject/1292052/reviews?start=0也有单独一篇影评的地址:
https://movie.douban.com/review/1234567/表面相似,实则需要不同的解析方式。
<a> 标签里,有时却嵌在别的节点中。最初写的字符串截取法,几乎每次都要改。那几天,我的脚本几乎是“跑一次,改一次”。
我后来重新梳理:真正困扰的核心是两个点。
于是我开始往正则表达式的方向想:能不能写一套更“宽容”的模式,把这些变动都涵盖进去?
经过几番尝试,慢慢找到了一些规律。
reviews?start=(\d+)review/(\d+)/(\d{4}[-/]\d{1,2}[-/]\d{1,2}(?:\s+\d{1,2}:\d{2}:\d{2})?)既能匹配“2023-08-27”,也能识别“2023-08-27 12:30:00”。
<a href="/people/[^"]+/">([^<]+)</a>一旦抽象成这些模式,后续就很顺畅了:URL 能自动识别类型,评论时间和作者也能统一提取。
下面是简化版的示例代码,加入了爬虫代理配置,提高采集成功率:
import re
import requests
# 代理设置(亿牛云示例)
proxy_host = "proxy.16yun.cn"
proxy_port = "31000"
proxy_user = "16YUN"
proxy_pass = "16IP"
proxies = {
"http": f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}",
"https": f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
}
# 示例:豆瓣影评第一页
url = "https://movie.douban.com/subject/1292052/reviews?start=0"
resp = requests.get(url, proxies=proxies, timeout=10)
html = resp.text
# 解析翻页参数
page_pattern = re.compile(r"reviews\?start=(\d+)")
page = page_pattern.search(url)
if page:
print("当前页码:", page.group(1))
# 提取影评 ID
review_pattern = re.compile(r"https://movie.douban.com/review/(\d+)/")
review_ids = review_pattern.findall(html)
print("影评ID示例:", review_ids[:5])
# 提取评论时间
time_pattern = re.compile(r"(\d{4}[-/]\d{1,2}[-/]\d{1,2}(?:\s+\d{1,2}:\d{2}:\d{2})?)")
times = time_pattern.findall(html)
print("评论时间:", times[:5])
# 提取作者昵称
author_pattern = re.compile(r'<a href="/people/[^"]+/">([^<]+)</a>')
authors = author_pattern.findall(html)
print("作者示例:", authors[:5])这次经历让我有些感触:
过去我写爬虫时,总是先考虑“跑通”,很少想“如果格式变了怎么办”。这次之后,我更习惯去总结模式,再去写代码。
一句话总结:采集豆瓣影评的过程,其实是一堂“模式化思维”的课。链接和字段表面上杂乱无章,但只要把变化抽象成规则,就能让代码更稳、更耐用。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。