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

如何使用Pyppeteer从Vanguard站点通过JS下载CSV/Excel文件

解决方案

核心问题根因

你当前代码无法触发下载主要有3个问题:

  • 未配置Pyppeteer的下载规则:Pyppeteer默认不会自动处理下载请求,需要手动指定下载路径、开启下载权限
  • 错误读取页面内容作为下载文件:点击下载按钮不会改变当前页面的HTML内容,你写入csv_page{i}.csv的内容始终是当前页面的源码,和目标下载文件无关
  • 固定延迟等待不稳定:固定2秒等待无法适配不同网络环境下的元素加载速度,容易出现点击未生效的问题

修改后可运行代码

import asyncio
from pyppeteer import launch
import os

async def get_page(browser, url):
    page = await browser.newPage()
    await page.goto(url, timeout=30000)
    return page

async def fetch(url):
    # 提前创建存储目录
    wkg_dir = 'vanguard'
    os.makedirs(wkg_dir, exist_ok=True)
    
    # 启动浏览器,调试阶段可以先关闭headless看操作流程
    browser = await launch(headless=False, options={'args': ['--no-sandbox']})
    page = await get_page(browser, url)
    
    # 配置下载规则,指定文件保存路径
    await page._client.send('Page.setDownloadBehavior', {
        'behavior': 'allow',
        'downloadPath': os.path.abspath(wkg_dir)
    })
    
    # 监听下载事件,确认文件下载完成
    async def on_download(download):
        save_path = await download.path()
        print(f"下载完成,文件路径:{save_path}")
        # 如果你需要自定义文件名可以在这里重命名
        # new_name = os.path.join(wkg_dir, "holdings.xlsx")
        # os.rename(save_path, new_name)
    page.on('download', lambda d: asyncio.create_task(on_download(d)))

    # 等待「See count total holdings」链接可点击
    await page.waitForXPath('//a[contains(., "See count total holdings")]', timeout=10000)
    accept = await page.xpath('//a[contains(., "See count total holdings")]')
    print(f'Found {len(accept)} "See count total holdings" links')
    
    if accept:
        # 避免元素遮挡导致点击失效,用JS执行点击
        await page.evaluate('el => el.click()', accept[0])
    else:
        print('DID NOT FIND THE LINK')
        await browser.close()
        return False
    
    # 等待「Export to CSV」链接加载完成
    await page.waitForXPath('//a[contains(., "Export to CSV")]', timeout=10000)
    links = await page.xpath('//a[contains(., "Export to CSV")]')
    print(f'Found {len(links)} "Export to CSV" links')

    # 点击对应导出链接,这里第三个链接是全部持仓的导出按钮,你可以根据自己的需要选
    target_link = links[2]
    await page.evaluate('el => el.click()', target_link)
    
    # 等待下载完成,可根据网络情况调整等待时间
    await page.waitFor(5000)
    
    await browser.close()
    return True

#---------- Main ------------
url = 'https://www.vanguard.com.au/personal/products/en/detail/8225/portfolio'
asyncio.run(fetch(url))

注意事项

  • 站点返回的实际是Excel格式文件,下载后可直接用pandas.read_excel读取,不需要强制转CSV
  • 如果需要部署到服务器运行,把launch的headless参数设为True即可,不影响下载逻辑
  • 如果出现元素找不到的报错,可以适当调大waitForXPath的timeout参数适配网络环境

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 17:30:04