使用Selenium和BeautifulSoup爬取评论时break语句失效问题
亚马逊评论爬虫break语句失效问题分析
问题描述
使用Selenium+BeautifulSoup爬取亚马逊德国站商品评论时,到达评论最后一页后,while循环并未终止,仍持续运行。预期中最后一页无「下一页」按钮,break语句应触发终止循环,但实际未生效。
用户代码
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 import pandas as pd from bs4 import BeautifulSoup driver = webdriver.Chrome() reviewlist= [] ASINs = ['B09SXL3HPG', 'B07TP8LLQZ'] for a in range(len(ASINs)): url = 'https://www.amazon.de/dp/' + str(ASINs[a]) driver.get(url) #Accept cookies (only if you need it) if a == 0: accept_cookies = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[id='sp-cc-accept']"))).click() #Go to all reviews WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "a[data-hook='see-all-reviews-link-foot']"))).click() while True: soup = BeautifulSoup(driver.page_source, 'html.parser') reviews = soup.find_all('div', {'data-hook': 'review'}) for item in reviews: review = { 'date': item.find('span', {'data-hook': 'review-date'}).text.strip(), 'body': item.find('span', {'data-hook': 'review-body'}).text.strip(), } reviewlist.append(review) try: next_page_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.a-pagination .a-last'))).click() print('click') time.sleep(1) except Exception as ex: print(ex,"!!!!!!!") break
问题原因
最后一页的「下一页」元素并未消失:亚马逊评论的最后一页中,
.a-pagination .a-last这个元素仍然存在于DOM中,只是被添加了a-disabled类,变成不可点击的状态。而代码中使用的presence_of_element_located条件只要检测到元素存在就会返回,不会判断元素是否可交互,因此不会触发异常,循环也就不会终止。异常触发逻辑不符合实际场景:当前代码只有在找不到「下一页」元素时才会进入except块执行break,但最后一页该元素实际存在,所以代码会一直尝试点击不可点击的元素,导致循环持续运行,重复爬取最后一页的评论。
修复方案
方案1:改用可点击条件判断
将presence_of_element_located替换为element_to_be_clickable,这样当元素存在但不可点击时,会触发超时异常,进而执行break:
try: next_page_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.a-pagination .a-last'))).click() print('click') time.sleep(1) except Exception as ex: print(ex,"!!!!!!!") break
方案2:检查元素是否被禁用
先定位到「下一页」元素,检查它是否包含a-disabled类,若包含则终止循环,否则点击:
try: next_page_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.a-pagination .a-last'))) if 'a-disabled' in next_page_button.get_attribute('class'): break next_page_button.click() print('click') time.sleep(1) except Exception as ex: print(ex,"!!!!!!!") break
内容的提问来源于stack exchange,提问作者Mina
相关产品推荐
相关产品推荐

