爬虫问题:尝试爬取多页名言却仅获取单页数据
修复Selenium爬取多页名言的问题及优化思路
修复方案
单页数据问题通常出在分页逻辑未正确实现或JS延迟加载处理不到位,以下是具体修复步骤:
1. 实现分页循环逻辑
核心是定位「下一页」按钮,循环判断其是否可点击(不存在或禁用则终止循环):
- 定位下一页按钮:通过
find_element(By.CSS_SELECTOR, ".next a") - 循环条件:每次爬取当前页后,尝试查找下一页按钮,若找不到或按钮不可点击则退出循环
2. 处理JS延迟加载
目标网站是JS渲染的延迟加载页面,必须用显式等待替代固定sleep,确保元素完全加载:
- 使用
WebDriverWait等待名言列表加载完成,示例:from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待名言列表加载 quotes = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".quote")) )
3. 翻页后重新定位元素
每次翻页后,页面DOM会更新,之前定位的元素会失效,需重新获取名言元素,避免StaleElementReferenceException。
完整修复代码示例
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 json driver = webdriver.Chrome() driver.get("http://quotes.toscrape.com/js-delayed/") with open("output.jsonl", "w", encoding="utf-8") as f: while True: # 等待当前页名言加载完成 quotes = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".quote")) ) # 解析当前页数据 for quote in quotes: text = quote.find_element(By.CSS_SELECTOR, ".text").text author = quote.find_element(By.CSS_SELECTOR, ".author").text tags = [tag.text for tag in quote.find_elements(By.CSS_SELECTOR, ".tag")] # 写入jsonl文件 json.dump({"text": text, "author": author, "tags": tags}, f) f.write("\n") # 尝试定位下一页按钮 try: next_btn = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, ".next a")) ) next_btn.click() except: # 没有下一页,退出循环 break driver.quit()
优化思路
- 使用无头浏览器:启用Chrome无头模式,减少资源占用,提升爬取速度
options = webdriver.ChromeOptions() options.add_argument("--headless=new") driver = webdriver.Chrome(options=options) - 批量写入数据:先将所有数据存入列表,最后一次性写入文件,减少IO操作次数
- 添加异常处理:对元素定位、点击等操作添加
try-except块,处理超时、元素不存在等异常,避免程序中途崩溃 - 封装页面操作:使用Page Object模式,将页面元素定位和操作封装成类,提升代码可维护性
- 断点续爬:记录已爬取的页码,程序中断后可从上次的页码继续爬取,避免重复劳动
内容的提问来源于stack exchange,提问作者tbone
相关产品推荐
相关产品推荐

