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

Scrapy+Selenium爬取时点击Load more按钮无响应问题求助

Scrapy+Selenium爬取新闻时Load More按钮点击失效解决方案

你遇到的元素能正常获取但点击无响应的问题,是Selenium爬取Algolia驱动的无限滚动列表(从按钮classais-InfiniteHits-loadMore可判断是Algolia搜索组件)的常见问题,以下是按优先级排序的可落地方案:

  • 修复遮挡问题,调整滚动位置
    你之前用ActionChains.move_to_element()默认会把元素滚到视口顶部,要是站点有fixed定位的顶部导航栏,按钮会被导航完全遮挡,点击坐标实际落在导航上,自然不会触发按钮逻辑。把滚动逻辑改成把按钮滚到视口中间,等滚动动画结束再点击:
    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
    
    load_more_btn = WebDriverWait(driver, 20).until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, ".ais-InfiniteHits-loadMore"))
    )
    # 把按钮滚动到视口正中间,避开顶部/底部固定栏遮挡
    driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", load_more_btn)
    time.sleep(0.5) # 等待滚动动画、页面重绘完成
    
  • 替换JS点击逻辑,补全事件链
    你之前用的driver.execute_script("arguments[0].click();", element)只触发了单一click事件,大部分站点的反爬逻辑会校验完整的鼠标交互事件链(mousedown -> mouseup -> click),单一事件触发会被直接拦截。换成完整事件派发的写法:
    driver.execute_script("""
        const targetBtn = arguments[0];
        // 按真实交互顺序派发鼠标事件
        const eventList = ['mousedown', 'mouseup', 'click'];
        eventList.forEach(eventName => {
            targetBtn.dispatchEvent(new MouseEvent(eventName, {
                bubbles: true,
                cancelable: true,
                view: window
            }));
        });
    """, load_more_btn)
    
  • 增加按钮状态校验,避开加载防抖期
    Algolia的无限滚动组件在加载新内容时,会自动给按钮加disabled属性,同时把按钮文本改成Loading...,这时候不管怎么点都不会触发新的加载请求。点击前先做状态判断:
    while True:
        btn_disabled = load_more_btn.get_attribute("disabled")
        btn_text = load_more_btn.text.strip()
        # 按钮非禁用、文本恢复为Load more时才允许点击
        if not btn_disabled and btn_text == "Load more":
            break
        time.sleep(0.3)
    
  • 排查iframe嵌套问题
    如果按钮被放在iframe内,哪怕你在主文档上下文拿到了WebElement实例,点击操作也不会生效。先执行代码检查页面iframe数量:
    iframe_list = driver.find_elements(By.TAG_NAME, "iframe")
    print(f"当前页面共有{len(iframe_list)}个iframe")
    
    如果存在iframe,先切换到按钮所在的iframe上下文,再执行元素查找和点击操作,操作完成后切回主文档即可:
    # 替换成按钮所在的iframe元素
    driver.switch_to.frame(iframe_list[0])
    # 执行查找、点击逻辑
    driver.switch_to.default_content()
    
  • 隐藏Selenium自动化特征绕过反爬
    如果以上方案都不生效,说明站点检测到了Selenium的自动化标识,拦截了交互行为。启动Chrome时加以下参数隐藏自动化特征:
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    
    chrome_options = Options()
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option("useAutomationExtension", False)
    driver = webdriver.Chrome(options=chrome_options)
    # 注入脚本修改navigator.webdriver检测标识
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
    })
    

全量加载新闻的参考循环逻辑

点击后要等待新内容渲染完成,再判断是否需要继续点击,避免操作过快被拦截:

# 替换成你自己的新闻条目选择器
NEWS_ITEM_SELECTOR = "替换成新闻条目的CSS选择器"
while True:
    try:
        load_more_btn = WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, ".ais-InfiniteHits-loadMore"))
        )
        # 把前面的滚动、状态校验、点击逻辑放在这里
        old_news_count = len(driver.find_elements(By.CSS_SELECTOR, NEWS_ITEM_SELECTOR))
        # 执行点击操作
        # 等待新内容加载完成(新闻条目数增加)
        WebDriverWait(driver, 10).until(
            lambda d: len(d.find_elements(By.CSS_SELECTOR, NEWS_ITEM_SELECTOR)) > old_news_count
        )
    except:
        # 找不到Load more按钮、超时没有新内容加载时,说明已经到列表底部,退出循环
        break

提示:你之前用的多层级绝对XPATH定位稳定性极差,页面DOM结构稍有变动就会定位失效,直接用按钮专属class做CSS选择器定位的可靠性高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:54:07