Selenium爬取亚马逊商品报NoSuchElementException无法定位下一页按钮
报错原因
报NoSuchElementException是因为下一页按钮的定位逻辑存在问题,具体诱因有4个:
- xpath写的是精确匹配
class='a-last',亚马逊分页栏的class经常会拼接动态生成的其他类名,精确匹配会直接失效 - 靠固定
sleep()等页面加载完全不靠谱,网络波动时元素还没渲染出来就执行查找,自然找不到目标节点 - 硬编码了爬10页的循环,但很多关键词的搜索结果总页数不足10页,爬到最后一页时下一页按钮要么置灰要么直接不渲染,继续查找必然报错
- 爬取频率过高触发亚马逊反爬人机验证时,页面结构完全变更,不存在分页相关元素
修复方案
- 替换定位规则:把精确class匹配改为包含匹配,优先定位
a-last节点下的可点击a标签,避免匹配到最后一页置灰的无效节点 - 替换固定等待为显式等待:设置最长等待时长,等元素完全加载、可点击之后再执行操作,不需要手动预估等待时间
- 增加异常捕获逻辑:找不到下一页按钮时直接终止循环,不要硬凑10页的爬取逻辑,此时要么是已经爬完所有结果,要么是被反爬机制拦截
- 高版本Selenium已经废弃
find_element_by_*系列旧写法,统一使用find_element(By.xxx, value)的新语法,避免后续版本兼容问题
修复后完整代码
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 from time import sleep path = '/usr/local/bin/chromedriver' browser = webdriver.Chrome(executable_path=path) browser.get('https://www.amazon.in') browser.maximize_window() # 执行搜索操作 input_search = browser.find_element(By.ID, 'twotabsearchtextbox') search_button = browser.find_element(By.XPATH, "(//input[@type='submit'])[1]") input_search.send_keys("protein") sleep(1) search_button.click() products = [] # 初始化最长10秒的显式等待 wait = WebDriverWait(browser, 10) for i in range(10): print(f'正在爬取第{i+1}页') # 等商品列表加载完成再提取数据 product_elements = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//span[@class='a-size-medium a-color-base a-text-normal']"))) for p in product_elements: products.append(p.text) try: # 定位可点击的下一页按钮 next_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//li[contains(@class,'a-last')]/a"))) # 滚动到按钮位置,避免懒加载拦截点击 browser.execute_script("arguments[0].scrollIntoView();", next_button) next_button.click() sleep(2) except Exception: print("无更多页面或触发反爬验证,终止爬取") break # 爬取完成后关闭浏览器 # browser.quit()
注意:爬取亚马逊不要设置过高的请求频率,短时间内请求过多很容易触发IP封禁,建议适当拉长请求间隔,有条件的可以搭配代理使用。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

