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

Selenium新手求助:抓取印尼央行2015-2020年汇率表时筛选控件报错

解决Selenium操作印尼央行汇率页面下拉框时的elementsFromPoint错误

嘿,作为Selenium新手遇到这个问题太正常了!我来帮你拆解一下问题根源,然后一步步给出可行的解决方案~

问题根源分析

你碰到的JavascriptException: Failed to execute 'elementsFromPoint' on 'Document': The provided double value is non-finite错误,本质上是Selenium尝试点击的元素坐标无效,常见原因包括:

  • 元素不在当前可视区域内(比如在屏幕外,导致浏览器计算坐标时出错)
  • 元素还没完全加载完成就被触发点击
  • 直接通过索引定位下拉选项太不稳定(页面结构一变就失效)
  • 下拉框本身需要先展开,才能点击里面的选项(你直接定位选项点击,可能下拉框还没激活)

分步解决方案

我把代码重新调整了,不仅解决下拉框的问题,还帮你处理日期筛选和表格抓取的部分,更可靠:

1. 初始化浏览器并确保页面加载完成

先最大化窗口避免元素被遮挡,用WebDriverWait替代固定等待,确保核心元素加载好再操作:

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
from selenium.webdriver.support.ui import Select
from bs4 import BeautifulSoup
import time

# 初始化浏览器,可选无头模式后台运行
options = webdriver.ChromeOptions()
# options.add_argument("--headless=new")  # 不需要可视化的话可以打开
driver = webdriver.Chrome(options=options)
driver.maximize_window()  # 最大化窗口,减少元素被遮挡的概率
driver.get("https://www.bi.go.id/id/moneter/informasi-kurs/transaksi-bi/Default.aspx")

# 等待页面核心容器加载完成,最多等10秒
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_pnlKurs")))

2. 正确操作货币筛选下拉框

不要直接定位选项,先处理下拉框本身:如果是标准的<select>标签,用Select类最省心;如果是JS渲染的自定义下拉框,就先点击展开再选选项:

情况1:标准<select>下拉框(推荐)

如果ctl00_PlaceHolderMain_biWebKursTransaksiBI_ddlmatauang1是标准select标签,直接用Select类操作,稳定又简单:

# 等待下拉框可点击
currency_select = wait.until(EC.element_to_be_clickable((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_ddlmatauang1")))
select = Select(currency_select)

# 推荐用文本选择,比索引稳定太多!比如选美元
select.select_by_visible_text("USD")
# 如果你一定要用索引,注意HTML里option的索引从0开始,你之前的option[24]对应索引23
# select.select_by_index(23)

情况2:自定义JS下拉框

如果是点击才展开的自定义下拉框,就先触发展开,再定位选项:

# 点击下拉框展开选项列表
currency_dropdown = wait.until(EC.element_to_be_clickable((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_ddlmatauang1")))
currency_dropdown.click()

# 等待目标选项加载完成,比如选USD
target_option = wait.until(EC.element_to_be_clickable((By.XPATH, "//select[@id='ctl00_PlaceHolderMain_biWebKursTransaksiBI_ddlmatauang1']/option[text()='USD']")))
# 如果选项在屏幕外,先滚动到它的位置
driver.execute_script("arguments[0].scrollIntoView();", target_option)
target_option.click()

3. 设置日期筛选(2015年11月-2020年11月)

页面的日期输入框可以直接输入日期,注意页面的日期格式是DD/MM/YYYY:

# 填充起始日期:2015年11月1日
start_date = wait.until(EC.element_to_be_clickable((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_txtStartDate")))
start_date.clear()
start_date.send_keys("01/11/2015")

# 填充结束日期:2020年11月30日
end_date = wait.until(EC.element_to_be_clickable((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_txtEndDate")))
end_date.clear()
end_date.send_keys("30/11/2020")

# 点击查询按钮
search_btn = wait.until(EC.element_to_be_clickable((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_btnSearch")))
search_btn.click()

# 等待结果表格加载完成
wait.until(EC.presence_of_element_located((By.ID, "ctl00_PlaceHolderMain_biWebKursTransaksiBI_gvKurs")))

4. 抓取汇率表格数据

表格加载好后,用BeautifulSoup解析提取数据:

# 获取页面源码,解析表格
page_source = driver.page_source
soup = BeautifulSoup(page_source, "html.parser")
rate_table = soup.find("table", id="ctl00_PlaceHolderMain_biWebKursTransaksiBI_gvKurs")

# 遍历表格行,跳过表头
for row in rate_table.find_all("tr")[1:]:
    cols = row.find_all("td")
    if cols:
        date = cols[0].text.strip()
        currency = cols[1].text.strip()
        buy_rate = cols[2].text.strip()
        sell_rate = cols[3].text.strip()
        print(f"日期: {date}, 货币: {currency}, 买入价: {buy_rate}, 卖出价: {sell_rate}")

几个关键提醒

  • 别用索引定位元素:页面更新后索引会变,用文本或ID定位才是长久之计
  • 一定要等元素可交互:用element_to_be_clickable确保元素能被点击,而不是仅仅存在于DOM中
  • 处理元素不可视:如果元素在屏幕外,用scrollIntoView()滚动过去再点击
  • 检查元素类型:区分标准select和自定义下拉框,用对应的操作方式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:28:01