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

Selenium Python爬取investidor10网站Vale股票分红数据时,分页按钮点击异常跳转的问题求助

Selenium Python爬取investidor10网站Vale股票分红数据时,分页按钮点击异常跳转的问题求助

看起来你踩了动态分页组件的经典坑——初始获取的分页按钮列表在页面跳转后会变成「过时元素(Stale Element)」,而且这个网站用的DataTables分页组件,当页码超过当前显示的按钮数量时,data-dt-idx的取值会和实际页码脱节,直接导致你点错页码。

你的代码核心问题分析:

  1. 提前缓存的按钮列表失效:你在iterar_botao()开头就获取了所有分页按钮,但当你点击第1页后,页面的分页按钮DOM已经重新渲染了,之前的botoes列表里的元素其实已经失效了,后续循环用i计算的idx自然和实际页面上的data-dt-idx不匹配。
  2. data-dt-idx属性不稳定:DataTables会动态调整这个属性的值,当页码过多时,它只会显示部分页码,其他用省略号代替,这时候data-dt-idx的编号和实际页码完全对应不上,你点data-dt-idx="5",实际可能跳到第8页。
  3. 等待条件不严谨:你用了presence_of_element_located,但这个条件只保证元素在DOM中存在,不代表它可以被点击,很容易出现点击无效的情况。

修正后的解决方案

我给你调整了代码逻辑,核心思路是放弃依赖data-dt-idx,改用总页数循环 + 页码文本定位,这样不管分页组件怎么动态变化,都能精准定位到目标页码:

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

def scrape_all_pages():
    # 先处理初始页面(第1页)
    pegar_tabelas()
    
    # 获取总页数:从分页栏的"X de Y"文本中提取Y
    total_pages = get_total_pages()
    for page_num in range(2, total_pages + 1):
        click_page_button(page_num)
        # 等待新页面数据加载完成
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "table-dividends-history"))
        )
        pegar_tabelas()

def get_total_pages():
    # 定位分页信息元素,比如"1 de 8"
    pagination_info = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "span.paginate_of"))
    )
    # 解析总页数
    return int(pagination_info.text.split(" de ")[-1])

def click_page_button(page_num):
    try:
        # 用页码文本定位,避开动态变化的data-dt-idx
        btn_selector = f'a.paginate_button:not(.disabled):not(.active) span:contains("{page_num}")'
        page_btn = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, btn_selector))
        )
        # 原生点击,自动处理滚动和可点击状态
        page_btn.click()
        # 等待旧表格失效,确保页面已经完成跳转
        WebDriverWait(driver, 10).until(
            EC.staleness_of(driver.find_element(By.ID, "table-dividends-history"))
        )
    except Exception as e:
        print(f"点击页码{page_num}失败: {str(e)}")

def pegar_tabelas():
    # 这里放你爬取表格数据的逻辑,注意每次都重新定位表格元素
    table = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "table-dividends-history"))
    )
    rows = table.find_elements(By.TAG_NAME, "tr")
    # 处理每行数据...
    print(f"已爬取当前页的{len(rows)-1}条数据(排除表头)")

# 初始化驱动并打开页面
driver = webdriver.Chrome()
driver.get("https://investidor10.com.br/acoes/vale3/")

# 关闭可能的弹窗(如果有)
try:
    close_btn = WebDriverWait(driver, 5).until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, "button.close"))
    )
    close_btn.click()
except:
    pass

# 执行爬取
scrape_all_pages()

# 关闭驱动
driver.quit()

关键优化点说明:

  1. 基于总页数循环:先从页面上提取总页数,再循环遍历每一页,避免依赖动态变化的分页按钮列表。
  2. 用页码文本定位按钮:直接通过按钮上的数字文本(比如"2"、"3")定位,完全避开data-dt-idx的动态变化问题。
  3. 严谨的等待条件:
    • 用element_to_be_clickable确保按钮可以被点击,而不是仅仅存在。
    • 用staleness_of等待旧表格元素失效,确保页面已经完成跳转。
  4. 移除不必要的sleep:用显式等待替代固定睡眠,代码更高效稳定。

如果还是遇到问题,可以检查:

  • 网站是否有反爬机制,比如需要登录或人机验证。
  • 分页栏的选择器是否正确,可以用浏览器开发者工具确认span.paginate_of是否是正确的总页数元素。
  • 表格爬取逻辑中,是否每次都重新定位表格元素,避免Stale Element错误。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:54:31