使用Selenium抓取动态JavaScript表格遇‘无法定位元素’问题求助
问题描述
我想要使用Selenium抓取网站https://polkadot.subscan.io/account/12xtAYsRUrmbniiWQqJtECiBQrMn8AypQcXhnQAc6RB6XkLW?tab=transfer中的“From、To、Value、Time”信息,存入pandas dataframe进行分析。但用Chrome复制XPath的方法尝试后失败,执行代码时出现no such element: Unable to locate element错误。我使用的代码如下:
link = "https://dotscan.com/account/13UVJyLnbVp9RBZYFwFGyDvVd1y27Tt8tkntv6Q7JVPhFsTB?tab=transfers" driver.get(link) download_btn = driver.find_element(By.XPATH, "//*[@id='rc-tabs-3-panel-1']/div/div[1]/div/table/tbody/tr[1]/td[6]/div/a") download_btn.click()
解决思路与方案
失效原因分析
- 页面动态加载:Subscan的转账数据是异步渲染的,代码执行时目标元素还未加载完成,直接查找必然失败。
- 动态ID不可靠:
rc-tabs-3-panel-1这类ID是前端框架动态生成的,页面刷新后可能变化,硬写定位会失效。 - 域名不匹配:代码中使用的
dotscan.com和目标网站polkadot.subscan.io不是同一站点,页面结构完全不同,自然找不到元素。
修正后代码示例(通过下载文件提取数据)
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 import pandas as pd # 替换为正确的目标链接 link = "https://polkadot.subscan.io/account/12xtAYsRUrmbniiWQqJtECiBQrMn8AypQcXhnQAc6RB6XkLW?tab=transfer" driver = webdriver.Chrome() driver.get(link) # 显式等待下载按钮加载完成(最长等待10秒) try: download_btn = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//a[text()='Download']")) ) download_btn.click() # 等待文件下载完成后,读取到dataframe(路径需根据浏览器默认下载目录调整) df = pd.read_csv("~/Downloads/transfers.csv") # 提取需要的列 target_df = df[["From", "To", "Value", "Time"]] print(target_df.head()) finally: driver.quit()
备用方案:直接抓取页面表格数据
如果下载按钮定位仍有问题,可以直接解析页面上的表格内容:
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 import pandas as pd link = "https://polkadot.subscan.io/account/12xtAYsRUrmbniiWQqJtECiBQrMn8AypQcXhnQAc6RB6XkLW?tab=transfer" driver = webdriver.Chrome() driver.get(link) # 等待表格加载完成 table = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "ant-table")) ) rows = table.find_elements(By.TAG_NAME, "tr") # 提取表头和数据行 headers = [th.text.strip() for th in rows[0].find_elements(By.TAG_NAME, "th")] data_rows = [] for row in rows[1:]: cols = [td.text.strip() for td in row.find_elements(By.TAG_NAME, "td")] data_rows.append(cols) # 转为dataframe并筛选目标列 df = pd.DataFrame(data_rows, columns=headers) target_df = df[["From", "To", "Value", "Time"]] print(target_df.head()) driver.quit()
内容的提问来源于stack exchange,提问作者Alejandro Castillo
相关产品推荐
相关产品推荐

