使用requests-html调用JS函数下载文件遇MaxRetries错误,求解决方案
解决表单触发的文件下载问题(绕开requests-html渲染失败)
方案一:直接模拟表单POST请求(最推荐,无需JS渲染)
本质上,点击Generate按钮的核心动作是提交frmCriterio表单到main_xml.asp,完全可以跳过JS执行,直接用requests/requests-html构造POST请求:
- 先访问目标页面,提取表单的所有字段(包括隐藏字段)
- 补充JS函数中声明的额外表单值(比如你的
prov_id) - 发送POST请求并保存响应内容
from requests_html import HTMLSession session = HTMLSession() # 1. 访问目标页面,获取表单和会话信息 target_url = "你的目标页面URL" response = session.get(target_url, cookies=cookies) # 2. 提取frmCriterio表单的所有字段 form = response.html.find('#frmCriterio', first=True) form_data = {} for elem in form.find('input, select, textarea'): name = elem.attrs.get('name') if name: form_data[name] = elem.attrs.get('value', '') # 3. 补充JS中设置的额外参数(比如prov_id对应的字段) # 替换成你实际需要设置的字段名和值 form_data["prov_id"] = prov_id # 4. 发送POST请求下载文件(如果是相对路径,需拼接完整URL) download_url = "main_xml.asp" if not download_url.startswith('http'): download_url = f"{response.url.rsplit('/', 1)[0]}/{download_url}" download_response = session.post(download_url, data=form_data, cookies=cookies) # 5. 保存文件(根据实际文件类型修改后缀) with open("downloaded_file.xml", "wb") as f: f.write(download_response.content)
方案二:修复requests-html的JS执行问题(若坚持用JS渲染)
如果一定要用requests-html执行JS,注意以下几点:
- 确保JS语法正确(原代码中
function formFunc{缺少括号,应为function formFunc() {) - 增加等待时间,确保页面完全加载后再执行JS
- 执行JS后,表单提交会触发页面跳转/下载,需捕获响应
from requests_html import HTMLSession session = HTMLSession() response = session.get(target_url, cookies=cookies) # 构造完整的可执行JS脚本 script = f""" function formFunc() {{ // 补充表单参数,替换成实际需要设置的内容 document.frmCriterio.prov_id = "{prov_id}"; document.frmCriterio.action = "main_xml.asp"; document.frmCriterio.target = "_self"; document.frmCriterio.submit(); }} formFunc(); """ # 调用render时增加等待时间和超时 try: response.html.render( script=script, cookies=cookies, wait=5, # 等待页面加载5秒 timeout=30, retries=3 ) # 若提交后跳转至下载页面,重新获取当前页面内容 current_response = session.get(response.html.url) with open("downloaded_file.xml", "wb") as f: f.write(current_response.content) except Exception as e: print(f"执行失败: {e}")
方案三:用Playwright替代(轻量无头浏览器,必要时迁移)
如果上述方案都不行,Playwright是比Selenium更简洁的无头浏览器方案,原生支持下载处理:
from playwright.sync_api import sync_playwright with sync_playwright() as p: # 启动Firefox无头浏览器(也可用Chrome/Edge) browser = p.firefox.launch(headless=True) page = browser.new_page() # 导入现有cookies(需确保domain匹配目标网站) page.add_cookies([ {"name": k, "value": v, "domain": "目标网站域名", "path": "/"} for k, v in cookies.items() ]) # 访问目标页面 page.goto(target_url) # 执行表单提交的JS page.evaluate(f"""() => {{ document.frmCriterio.prov_id = "{prov_id}"; document.frmCriterio.action = "main_xml.asp"; document.frmCriterio.target = "_self"; document.frmCriterio.submit(); }}""") # 等待下载完成并保存 download = page.wait_for_download() download.save_as("downloaded_file.xml") browser.close()
内容的提问来源于stack exchange,提问作者Ari Frid
相关产品推荐
相关产品推荐

