如何用Python直接下载网页表单提交导出的CSV文件
解决training.gov.au直接读取导出CSV的问题
核心思路
网站导出CSV通常需要维持会话、携带验证令牌,且大概率是POST请求而非GET——这就是你用requests.get()只拿到页面源码的原因。以下是不用Selenium的实现步骤:
步骤1:建立会话并获取必要验证信息
先访问搜索页面,获取会话Cookie和防CSRF的验证令牌(大部分网站都会要求这个):
import requests from bs4 import BeautifulSoup # 初始化会话,自动维持Cookie session = requests.Session() # 访问搜索页面,获取会话信息和验证令牌 search_page_url = "https://training.gov.au/Search" res = session.get(search_page_url) soup = BeautifulSoup(res.text, "html.parser") # 提取页面中的验证令牌 csrf_token = soup.find("input", {"name": "__RequestVerificationToken"})["value"]
步骤2:构造导出CSV的请求参数
通过浏览器开发者工具(F12→网络面板),点击导出CSV按钮,查看实际发送的请求:
- 确认导出接口的URL(通常类似
/Search/ExportToCsv) - 确认需要携带的参数,包括
ScopeNationalCode(支持多个值)、导出类型等
示例参数构造:
export_url = "https://training.gov.au/Search/ExportToCsv" # 构造请求参数,ScopeNationalCode可以传多个值(列表形式) request_data = { "__RequestVerificationToken": csrf_token, "ScopeNationalCode": ["FNS40217", "CHC30113"], # 示例编码,替换成你的目标编码 "ExportType": "Csv", "PageSize": 10000, # 设置足够大的值,确保一次性导出所有匹配记录 # 其他参数可从开发者工具的请求中复制,比如搜索关键词、筛选条件等 } # 设置请求头,告诉服务器我们要CSV格式的响应 headers = { "Accept": "text/csv", "Content-Type": "application/x-www-form-urlencoded" }
步骤3:发送请求并直接读取CSV
发送POST请求后,直接将响应内容转为可读取的文件对象,无需本地保存:
import csv import io # 可选:用pandas处理的话导入pandas # import pandas as pd # 发送导出请求 export_res = session.post(export_url, data=request_data, headers=headers) # 验证响应是否成功返回CSV if export_res.status_code == 200 and "text/csv" in export_res.headers["Content-Type"]: # 将响应文本转为内存文件对象 csv_buffer = io.StringIO(export_res.text) # 方式1:用csv模块逐行读取 csv_reader = csv.reader(csv_buffer) for row in csv_reader: print(row) # 替换成你的业务逻辑 # 方式2:用pandas直接转为DataFrame # df = pd.read_csv(csv_buffer) # print(df.head()) else: print("导出失败,返回内容:", export_res.text)
关键注意事项
- 必须用Session:维持会话Cookie,网站会验证请求是否来自合法会话
- 验证令牌不可少:
__RequestVerificationToken是防CSRF的关键,必须从搜索页面源码中提取 - 参数要准确:所有参数(包括隐藏字段)都要从浏览器的请求中复制,网站可能会校验参数完整性
- PageSize设足够大:避免分页导出,确保一次性获取所有匹配记录
内容的提问来源于stack exchange,提问作者babaganouj25
相关产品推荐
相关产品推荐

