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

使用Selenium获取CSV下载链接并导入Pandas DataFrame遇问题

问题分析与解决方案

为什么Selenium抓取的href为空?

你访问的这个新西兰统计局COVID dashboard是基于Shiny框架开发的,这类应用的下载链接有两个关键特性:

  • 动态生成+会话绑定:只有当你点击弹窗里的下载按钮时,后端才会生成一个临时的、和当前浏览器会话绑定的下载链接,再通过JavaScript把链接填充到按钮的href属性里。
  • 等待逻辑不匹配:你用的EC.presence_of_element_located只保证元素出现在DOM中,但此时JavaScript可能还没完成href的填充,所以拿到的是初始空值;另外直接获取outerHTML可能拿到的是元素刚创建时的静态HTML,而非更新后的状态。

改进的Selenium实现方法

我们可以调整等待逻辑,确保等到href属性不为空再获取,同时直接读取元素的href属性(比outerHTML更可靠):

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

driver = webdriver.Chrome(executable_path=r'/usr/local/bin/chromedriver')
URL = 'https://statisticsnz.shinyapps.io/covid_19_dashboard/'
driver.get(URL)

try:
    # 等待并点击"Download Data"按钮打开弹窗
    download_btn = WebDriverWait(driver, 15).until(
        EC.element_to_be_clickable((By.ID, 'download_data-show'))
    )
    download_btn.click()
    
    # 等待下载按钮的href属性填充完成(不为空)
    csv_link = WebDriverWait(driver, 15).until(
        lambda d: d.find_element(By.ID, 'download_data-downloadData').get_attribute('href') != ''
    )
    
    # 直接用pandas读取CSV
    df = pd.read_csv(csv_link)
    print(df.head())
finally:
    driver.quit()

更高效的替代方案:捕获网络请求

如果不想依赖页面元素的交互状态,还可以用Selenium的网络日志捕获下载请求的URL——Shiny的下载本质是一个GET请求,我们可以过滤出对应的请求链接:

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
import json

# 配置Chrome以捕获网络请求日志
chrome_options = webdriver.ChromeOptions()
chrome_options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})

driver = webdriver.Chrome(executable_path=r'/usr/local/bin/chromedriver', options=chrome_options)
URL = 'https://statisticsnz.shinyapps.io/covid_19_dashboard/'
driver.get(URL)

try:
    # 打开下载弹窗
    download_btn = WebDriverWait(driver, 15).until(
        EC.element_to_be_clickable((By.ID, 'download_data-show'))
    )
    download_btn.click()
    
    # 点击下载按钮触发请求
    csv_download_btn = WebDriverWait(driver, 15).until(
        EC.element_to_be_clickable((By.ID, 'download_data-downloadData'))
    )
    csv_download_btn.click()
    
    # 从网络日志中过滤出下载链接
    logs = driver.get_log('performance')
    download_url = None
    for log in logs:
        log_entry = json.loads(log['message'])['message']
        if log_entry['method'] == 'Network.requestWillBeSent' and 'download_data-downloadData' in log_entry['params']['request']['url']:
            download_url = log_entry['params']['request']['url']
            break
    
    if download_url:
        df = pd.read_csv(download_url)
        print(df.head())
finally:
    driver.quit()

注意事项

  • Shiny生成的下载链接是会话专属的,有效期很短,必须在同一个浏览器会话中获取链接后立即用pandas读取。
  • 确保你的ChromeDriver版本和本地Chrome浏览器版本完全匹配,避免兼容性问题导致的元素定位或网络日志捕获失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:22:32