Selenium+BeautifulSoup爬取评论find_all返回空列表解决方法
问题原因
代码返回空列表核心是两个问题:
- 页面评论区是异步动态渲染的,调用
driver.get()之后立刻取page_source时,评论节点还没加载到DOM树里,自然匹配不到目标元素 - 站点首次打开会弹出Cookie授权弹窗,部分场景下会阻塞页面后续内容渲染,不处理的话会导致评论区一直无法加载完成
修正方案
- 引入Selenium显式等待模块,等目标评论节点完全加载后再获取页面源码
- 页面加载完成后优先关闭Cookie弹窗,避免阻塞内容渲染
- 滚动到评论区所在位置,触发评论模块的加载逻辑
修正后的可运行代码如下:
from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time driver = webdriver.Chrome() # 打开目标评论页 driver.get('https://www.flaconi.de/haare/kerastase/chronologiste/kerastase-chronologiste-bain-regenerant-haarshampoo.html?yoReviewsPage=2') # 优先处理Cookie弹窗,最多等10秒,出现就点击同意 try: cookie_accept_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, 'button#onetrust-accept-btn-handler')) ) cookie_accept_btn.click() except: # 没弹出Cookie窗就直接跳过 pass # 滚动到页面60%高度位置,触发评论区加载 driver.execute_script("window.scrollTo(0, document.body.scrollHeight * 0.6)") time.sleep(1) # 显式等待最多15秒,直到评论节点全部加载到DOM中 WebDriverWait(driver, 15).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'div.content-review')) ) # 节点加载完成后再解析源码 soup = BeautifulSoup(driver.page_source, 'lxml') review_divs = soup.find_all('div', class_='content-review') # 提取所有评论文本 all_reviews = [div.get_text(strip=True) for div in review_divs] print(all_reviews) # 用完关闭浏览器实例 driver.quit()
补充注意事项
- 如果要爬取多页评论,每次点击分页切换按钮之后,都要重新等待新一页的
.content-review节点加载完成,再重新解析源码,不要点击后立刻取页面内容 - 尽量用显式等待代替固定时长的
time.sleep(),前者会在节点加载完成后立刻执行后续逻辑,效率更高,也不会因为网络波动导致等待时间不足、节点没加载出来的问题 - 如果运行后还是匹配不到,可以先打印
driver.page_source查看实际返回的DOM结构,确认class名是否有临时变动,目前该站点的评论节点class确实为content-review,等待加载完成后即可正常匹配
内容的提问来源于stack exchange,提问作者Bill Lin
相关产品推荐
相关产品推荐

