Python实现PubMed CSV导出自动化:解决403无效安全令牌问题
解决PubMed历史数据CSV下载403(无效安全令牌)问题
问题场景
需求:使用Python自动化下载PubMed(搜索词IBD)上的历史数据CSV文件,站点允许爬取且提供导出按钮。尝试代码后出现403错误,提示“invalid security token”,寻求无需Selenium的解决方法。
问题根源
你的代码存在两个核心问题:
- CSRF令牌获取方式错误,PubMed的CSRF令牌与会话Cookie绑定,单独提取令牌无法通过验证
- 请求URL拼接错误,将相对路径与带搜索参数的URL拼接,导致请求地址无效
修正方案
以下是无需Selenium的可行代码,核心是维持会话一致性、正确提取令牌与拼接URL:
import requests from bs4 import BeautifulSoup def parse_history(): # 初始化会话,自动维护Cookie session = requests.Session() base_domain = "https://pubmed.ncbi.nlm.nih.gov" search_url = f"{base_domain}/?term=IBD" # 首次请求获取页面、会话Cookie web_page = session.get(search_url) soup = BeautifulSoup(web_page.content, "html.parser") # 定位导出表单 form = soup.find('form', id='side-export-search-by-year-form') if not form: print("未找到历史数据导出表单") return # 拼接完整下载URL download_path = form.get('action') full_download_url = f"{base_domain}{download_path}" # 提取表单默认字段 form_data = {} for input_field in form.find_all('input'): field_name = input_field.get('name') field_value = input_field.get('value') if field_name: form_data[field_name] = field_value # 从页面meta标签提取有效CSRF令牌 csrf_token = soup.find('meta', attrs={'name': 'csrf-token'})['content'] form_data["csrfmiddlewaretoken"] = csrf_token # 提交下载请求 response = session.post(full_download_url, data=form_data) response.raise_for_status() # 主动抛出请求错误 # 保存CSV文件 with open('history.csv', 'wb') as f: f.write(response.content) print("历史数据CSV下载完成") if __name__ == "__main__": parse_history()
关键修改说明
- 使用
requests.Session():维持会话状态,自动携带Cookie,确保CSRF令牌与Cookie的绑定验证通过 - 正确拼接URL:将导出接口的相对路径与域名拼接,避免出现重复路径的无效地址
- 直接提取页面内的CSRF令牌:从页面的
<meta name="csrf-token">标签获取,无需额外函数,保证令牌与当前会话匹配
内容的提问来源于stack exchange,提问作者Paz
相关产品推荐
相关产品推荐

