You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

爬虫问题:尝试爬取多页名言却仅获取单页数据

修复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()

优化思路

  1. 使用无头浏览器:启用Chrome无头模式,减少资源占用,提升爬取速度
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    driver = webdriver.Chrome(options=options)
    
  2. 批量写入数据:先将所有数据存入列表,最后一次性写入文件,减少IO操作次数
  3. 添加异常处理:对元素定位、点击等操作添加try-except块,处理超时、元素不存在等异常,避免程序中途崩溃
  4. 封装页面操作:使用Page Object模式,将页面元素定位和操作封装成类,提升代码可维护性
  5. 断点续爬:记录已爬取的页码,程序中断后可从上次的页码继续爬取,避免重复劳动

内容的提问来源于stack exchange,提问作者tbone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:32:13