使用 Playwright 获取大众点评店铺评论
目录
简单记录使用playwright
获取大众点评店铺评论的方法。
大概一年前使用playwright
替换了selenium
写爬虫,使用playwright
自带脚本生成简单的代码并且保存登陆状态更加方便。最近因为某个原因要写一下大众点评的爬虫,简单记录一下整个过程。
在终端中执行下面的命令,开始代码生成。在弹出的浏览器窗口中访问网站,并登录。相关的一系列行为都会被记录下来,并生成对应的代码。当关闭代码生成界面之后,登陆状态也会被保存在指定的 session.json
文件下。
python -m playwright codegen --save-storage=session.json
下面是获取评论区脚本的具体实现方式。
- 首先加载已经保存过的 session.json 文件,之后创建一个
page
并且访问到指定的地址,并执行一行js命令让页面滑动到最底部。(页面滑动功能本来我不会写,但使用 copilot 给出注释之后它自动帮我补全了) - 等待所有的评论区被加载完成,这里用到了
wait_for_selector
使脚本强制等待 - 定位 comments 列表,把列表中的所有项遍历,保存我们想要的信息
- 因为这个网站的下一页按钮是不会发生变化的,所以在执行完访问功能之后会直接点击按钮,并等待几秒钟避免频率过高被反爬
这段代码执行了大概半个小时爬完了大概是三百多页的数据,每页15个评论。过程中只出现一次要求输入滑动验证的情况,由于设置了等待加载,手动输入验证之后就可以继续工作,之后就再也没有出现过相关的提示,可能是这个访问频率设置还比较合理。
# 使用 playwright 加载本地 session.json
# 访问 https://www.dianping.com/shop/l9dVct5Ly4pFdw9e/review_all
# 记录所有评论ID和链接
# 自动翻页
from playwright.sync_api import sync_playwright
fname = 'comments.csv'
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
# 加载session
context = browser.new_context(storage_state='session.json')
page = context.new_page()
# 访问评论页面
page.goto('https://www.dianping.com/shop/l9dVct5Ly4pFdw9e/review_all')
while True:
# 滑动到底部
page.evaluate('''() => {
window.scrollTo(0, document.body.scrollHeight);
}''')
# 等待评论加载完成
page.wait_for_selector(
'#review-list > div.review-list-container > div.review-list-main > div.reviews-wrapper > div.reviews-items')
# 获取评论ID和链接保存到csv文件
comments = page.query_selector_all(
'#review-list > div.review-list-container > div.review-list-main > div.reviews-wrapper > div.reviews-items > ul > li')
# 输出评论个数
print(len(comments))
for comment in comments:
# 获取用户名和链接 .div > div.dper-info > a
user = comment.query_selector('.dper-info > a')
# 用户名被 a 包裹
user_name = user.inner_text()
user_url = user.get_attribute('href')
print(user_name, user_url)
# 获取评论内容 #review-list > div.review-list-container > div.review-list-main > div.reviews-wrapper > div.reviews-items > ul > li:nth-child(2) > div > div.review-words.Hide
comment_content = comment.query_selector('.review-words').inner_text()
# 去除评论中的换行符和多余空格
comment_content = comment_content.replace('\n', '').replace(' ', '')
# 评论时间 #review-list > div.review-list-container > div.review-list-main > div.reviews-wrapper > div.reviews-items > ul > li:nth-child(2) > div > div.misc-info.clearfix > span.time
comment_time = comment.query_selector('.misc-info.clearfix > span.time').inner_text()
# 写入csv文件
with open(fname, 'a', encoding='utf-8') as f:
f.write(f'{user_name},{user_url},{comment_content},{comment_time}\n')
# 翻页 #review-list > div.review-list-container > div.review-list-main > div.reviews-wrapper > div.bottom-area.clearfix > div > a.NextPage
next_page = page.query_selector('#review-list > div.review-list-container > div.review-list-main > div.reviews-wrapper > div.bottom-area.clearfix > div > a.NextPage')
if next_page:
# 点击下一页
next_page.click()
else:
break
# 等待5秒
page.wait_for_timeout(5000)
一个现实的问题是,大众点评的评论区用到了 CSS 反爬虫,但由于我只需要 ID 和大概的评论内容,就没有深追,网上有很多博客讨论了如何破解 CSS 反爬。