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

如何用scrapy-selenium实现加载更多分页,获取响应却爬取不到内容怎么解决?

问题原因
  • 未等待异步加载完成:点击「加载更多」按钮后,页面请求新数据、渲染新节点需要一定时间,代码未做任何等待直接读取当前page_source,此时新内容还未插入DOM结构,XPath无法匹配到对应节点,最终返回空结果。
  • 初始页面内容漏爬:现有逻辑是先执行点击加载更多操作,再提取节点数据,页面首次加载完成就已经渲染的第一批内容被完全跳过,没有被爬取。
  • 点击逻辑稳定性不足:使用ActionChains的move_to_element+click组合,在元素未完全进入视口、被其他元素遮挡的场景下容易出现点击失效,没有触发新内容加载。
  • 变量命名风险:使用next作为变量名覆盖了Python内置的next()函数,可能引发不可预知的异常。
修复方案
  1. 进入页面后先提取首次渲染的内容,再执行加载更多的循环逻辑,避免漏爬首屏数据
  2. 点击加载更多后添加显式等待,通过页面高度变化、节点数量变化判断新内容是否加载完成,不要使用固定时长的sleep
  3. 替换点击逻辑,优先使用JS执行点击操作,避免元素交互限制导致的点击失效
  4. 新增加载失败兜底逻辑,避免按钮存在但无法点击时进入死循环
修正后代码
import scrapy
from scrapy.selector import Selector
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from time import sleep

class ProductSpider(scrapy.Spider):
    name = "card"
    start_urls = ['https://examplesite.com']

    def __init__(self):
        self.driver = webdriver.Chrome()
        # 显式等待最长时间,可根据页面加载速度调整
        self.wait = WebDriverWait(self.driver, 10)

    def parse(self, response):
        self.driver.get(response.url)
        # 先提取首屏已加载的内容
        for item in self.extract_content(self.driver.page_source):
            yield item
        # 记录当前页面高度,用于判断是否加载出新内容
        last_height = self.driver.execute_script("return document.body.scrollHeight")

        while True:
            # 查找加载更多按钮
            show_more_btns = self.driver.find_elements_by_css_selector("button#show-more")
            # 按钮不存在、或按钮已禁用则终止循环
            if not show_more_btns or not show_more_btns[0].is_enabled():
                break
            
            show_more_btn = show_more_btns[0]
            # 滚动到按钮位置
            self.driver.execute_script("arguments[0].scrollIntoView();", show_more_btn)
            # 用JS执行点击,避免元素交互限制
            self.driver.execute_script("arguments[0].click();", show_more_btn)

            try:
                # 等待页面高度变化,确认新内容加载完成
                self.wait.until(
                    lambda d: d.execute_script("return document.body.scrollHeight") > last_height
                )
                # 更新页面高度
                last_height = self.driver.execute_script("return document.body.scrollHeight")
                # 提取新加载的内容
                for item in self.extract_content(self.driver.page_source):
                    yield item
            except:
                # 超时未加载出新内容,终止循环
                break

        self.driver.close()
    
    def extract_content(self, page_source):
        """单独封装内容提取逻辑"""
        lists = Selector(text=page_source)
        for item in lists.xpath('//ul[@id="finder-table"]/li'):
            yield{
                'Name': item.xpath('.//*[@class="table-item-heading-product-name"]/span/strong/text()').get(),
                'Title': item.xpath('.//*[@class="table-item-heading-product-name"]/span/text()').get()
            }

如果修改后还是无法提取到内容,可以先打印self.driver.page_source检查实际渲染的DOM结构,确认XPath选择器和页面实际结构是否匹配。

内容的提问来源于stack exchange,提问作者Md. Fazlul Hoque

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 12:06:03