Selenium Python爬取investidor10网站Vale股票分红数据时,分页按钮点击异常跳转的问题求助
Selenium Python爬取investidor10网站Vale股票分红数据时,分页按钮点击异常跳转的问题求助
看起来你踩了动态分页组件的经典坑——初始获取的分页按钮列表在页面跳转后会变成「过时元素(Stale Element)」,而且这个网站用的DataTables分页组件,当页码超过当前显示的按钮数量时,data-dt-idx的取值会和实际页码脱节,直接导致你点错页码。
你的代码核心问题分析:
- 提前缓存的按钮列表失效:你在
iterar_botao()开头就获取了所有分页按钮,但当你点击第1页后,页面的分页按钮DOM已经重新渲染了,之前的botoes列表里的元素其实已经失效了,后续循环用i计算的idx自然和实际页面上的data-dt-idx不匹配。 data-dt-idx属性不稳定:DataTables会动态调整这个属性的值,当页码过多时,它只会显示部分页码,其他用省略号代替,这时候data-dt-idx的编号和实际页码完全对应不上,你点data-dt-idx="5",实际可能跳到第8页。- 等待条件不严谨:你用了
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()
关键优化点说明:
- 基于总页数循环:先从页面上提取总页数,再循环遍历每一页,避免依赖动态变化的分页按钮列表。
- 用页码文本定位按钮:直接通过按钮上的数字文本(比如"2"、"3")定位,完全避开
data-dt-idx的动态变化问题。 - 严谨的等待条件:
- 用
element_to_be_clickable确保按钮可以被点击,而不是仅仅存在。 - 用
staleness_of等待旧表格元素失效,确保页面已经完成跳转。
- 用
- 移除不必要的sleep:用显式等待替代固定睡眠,代码更高效稳定。
如果还是遇到问题,可以检查:
- 网站是否有反爬机制,比如需要登录或人机验证。
- 分页栏的选择器是否正确,可以用浏览器开发者工具确认
span.paginate_of是否是正确的总页数元素。 - 表格爬取逻辑中,是否每次都重新定位表格元素,避免Stale Element错误。
内容来源于stack exchange
相关产品推荐
相关产品推荐

