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

修复Selenium ActionChains循环分页爬取仅获对应序号内容的问题

问题修复方案

你的核心问题是循环逻辑错误:当前代码把「单页爬取单个问题」和「翻页」放在同一个循环里,导致第i次循环只爬取当前页的第i个问题,然后直接翻页,自然每页只拿到1个内容。

修复步骤:

  1. 拆分循环层级:外层循环控制翻页次数,内层循环负责爬取当前页的全部15个问题。
  2. 重新定位元素:每次进入新页面后,必须重新获取所有card-topic元素,避免页面刷新导致的「元素过时」错误。
  3. 替换硬等待:用WebDriverWait替代time.sleep,提升稳定性和效率。
  4. 增加翻页判断:检查「Selanjutnya」按钮是否可点击,避免最后一页无下一页时抛出异常。

修改后的完整代码:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoSuchElementException, TimeoutException

question_data = []
max_pages = 5  # 按需设置要爬取的总页数,或者改成循环直到无下一页

def expand_shadow_element(element):
    return driver.execute_script('return arguments[0].shadowRoot', element)

for page in range(max_pages):
    try:
        # 等待当前页的所有card-topic加载完成
        WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#topic-list card-topic'))
        )
        # 获取当前页所有问题元素
        topic_cards = driver.find_elements(By.CSS_SELECTOR, '#topic-list card-topic')
        
        # 内层循环爬取当前页的15个问题
        for card in topic_cards:
            shadow_root = expand_shadow_element(card)
            # 点击进入问题详情页
            shadow_root.find_element(By.CSS_SELECTOR, 'a').click()
            
            # 等待详情页的user-topic加载完成
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, 'user-topic'))
            )
            qt = driver.find_element(By.CSS_SELECTOR, 'user-topic')
            qt_root = qt.shadow_root
            qt_ele = qt_root.find_element(By.CSS_SELECTOR, 'p')
            question_data.append(qt_ele.text)
            
            # 返回列表页
            driver.back()
            # 等待列表页重新加载完成
            WebDriverWait(driver, 10).until(
                EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#topic-list card-topic'))
            )
        
        # 执行翻页操作
        paginate = driver.find_element(By.CSS_SELECTOR, 'paginate-button')
        paginate_root = expand_shadow_element(paginate)
        try:
            paginate2 = paginate_root.find_element(By.LINK_TEXT, 'Selanjutnya')
            # 检查按钮是否可点击
            if paginate2.is_enabled():
                actions = ActionChains(driver)
                actions.move_to_element(paginate2).click().perform()
                # 等待下一页加载完成
                WebDriverWait(driver, 10).until(
                    EC.staleness_of(topic_cards[0])  # 等待旧页面元素失效,说明新页面已加载
                )
            else:
                break  # 按钮不可点击,结束循环
        except NoSuchElementException:
            break  # 无下一页按钮,结束循环
            
    except TimeoutException:
        print(f"第{page+1}页加载超时,跳过")
        continue

print(f"共爬取{len(question_data)}个问题")

关键说明:

  • 双层循环:外层控制翻页,内层遍历当前页所有问题,确保每页15个都能被爬取。
  • 显式等待:用WebDriverWait等待元素加载,比time.sleep更灵活,能适应不同网络速度。
  • 元素重新定位:每次回到列表页和进入新页面后,都重新获取元素,避免StaleElementReferenceException。
  • 翻页边界处理:判断下一页按钮是否存在、是否可用,防止最后一页报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:01:04