动态页面评论提取异常:点击加载后JSON数据未同步更新
为什么点击加载更多后,#__NEXT_DATA__的JSON只有初始评论,而BeautifulSoup能拿到全部?
问题背景
我从https://www.kununu.com/de/adidas/kommentare抓取数据,用Selenium处理动态加载,点击了2次“Read more reviews”按钮加载更多评论。现在发现BeautifulSoup解析页面源码能拿到所有加载的评论,但从页面的#__NEXT_DATA__节点提取的JSON里只有首次加载的10条评论。
当前代码:
driver = webdriver.Chrome() driver.get(url) consent_accept_button(driver) show_more_reviews(driver, 2) soup = BeautifulSoup(driver.page_source, "html.parser") JSON = json.loads(soup.select_one("#__NEXT_DATA__").text) driver.quit()
差异原因
这是该站点使用的Next.js框架的典型行为:
#__NEXT_DATA__节点里的JSON是服务器端初始渲染时注入的静态数据,仅包含页面首次加载的10条评论。- 点击“加载更多”时,页面通过前端AJAX请求获取新评论,直接将新内容渲染到DOM中,但不会更新
#__NEXT_DATA__这个初始节点的内容。所以无论加载多少新评论,这个节点的JSON始终是最初的那批数据。 - 而BeautifulSoup解析的是当前完整的DOM源码,自然能包含所有已渲染到页面上的评论。
让JSON包含所有已加载评论的方法
你有几个可选方案:
方案1:直接从DOM提取评论(你已在使用的方式)
既然BeautifulSoup能拿到所有评论,直接解析DOM结构提取所需数据即可,无需依赖#__NEXT_DATA__的JSON。这是最直接的方式,毕竟你已经能获取完整的DOM内容。
方案2:模拟前端AJAX请求获取更多评论
打开浏览器开发者工具的“网络”面板,观察点击“加载更多”时发送的API请求。这类请求通常带有分页参数(比如page、offset),你可以直接用requests库调用这些API,获取所有评论的JSON数据,效率比用Selenium模拟浏览器更高。
方案3:用Selenium执行JS获取前端状态里的最新数据
如果一定要从前端状态拿JSON格式的全量评论,可以通过Selenium执行JavaScript,直接读取页面的全局数据或React组件状态。示例代码如下(需根据站点实际代码结构调整):
# 执行JS获取前端存储的所有评论数据 all_reviews = driver.execute_script(""" // 需根据站点实际代码找到存储评论的位置,以下是示例逻辑 return window.__REDUX_STORE__.getState().reviews.list; """) # 转换为JSON格式 import json reviews_json = json.dumps(all_reviews)
注意:这种方式需要你查看站点前端代码结构,找到存储评论的具体变量或状态,不同站点实现不同,需针对性调整。
内容的提问来源于stack exchange,提问作者user23501892
相关产品推荐
相关产品推荐

