Python Selenium点击下载按钮时如何获取服务器返回的下载链接
Selenium获取JS触发的真实下载链接实现方案
目标按钮无静态href属性,通过onclick触发env.downloadVideo(35678)执行下载逻辑,真实下载地址由JS动态生成/接口返回,以下是3种可直接落地的实现方式,按稳定性优先级排序:
方案1:拦截网络请求捕获下载地址(优先推荐)
原理:开启Chrome性能日志监听所有网络请求/响应,匹配下载链接特征直接抓取,不会触发实际文件下载,稳定性最高。
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By import json import re # Chrome基础配置 chrome_opt = Options() # 开启性能日志权限,用于捕获网络请求 chrome_opt.set_capability("goog:loggingPrefs", {"performance": "ALL"}) # 无头模式按需开启,不需要可注释 # chrome_opt.add_argument("--headless=new") driver = webdriver.Chrome(options=chrome_opt) # 替换为你的目标页面地址 driver.get("目标页面URL") # 下载链接匹配规则,可根据站点实际返回格式调整 # 示例匹配常见下载后缀、带download/file/video关键字的链接 url_pattern = re.compile( r'(https?://[^\s"\']+\.(mp4|zip|rar|mkv|exe|apk)[^\s"\']*)|(https?://[^\s"\']*(down|download|file|video)[^\s"\']*)', re.I ) real_download_url = None # 定位并点击下载按钮 driver.find_element(By.CSS_SELECTOR, "a.down_t").click() # 遍历性能日志匹配下载链接 for log_entry in driver.get_log("performance"): log_data = json.loads(log_entry["message"])["message"] # 监听网络响应接收事件 if log_data["method"] == "Network.responseReceived": current_url = log_data["params"]["response"]["url"] if url_pattern.search(current_url): real_download_url = current_url break print(f"捕获到真实下载地址:{real_download_url}") driver.quit()
适配提示:如果下载地址是POST接口返回体里的字段,不是直接在请求URL上,可将监听事件替换为Network.loadingFinished,额外获取对应请求的响应体解析即可。
方案2:JS Hook劫持下载函数
原理:在页面上下文重写目标下载函数、DOM方法或跳转方法,直接拦截JS执行过程中生成的下载地址,不需要遍历全量网络日志。
from selenium import webdriver from selenium.webdriver.common.by import By import time driver = webdriver.Chrome() # 替换为你的目标页面地址 driver.get("目标页面URL") # 注入JS劫持逻辑 hook_script = """ window._realDownloadUrl = null; // 保存原下载函数引用 const _originDownload = env.downloadVideo.bind(env); // 重写下载函数 env.downloadVideo = function(vid) { // Hook a标签创建逻辑,拦截href赋值 const _originCreateA = document.createElement.bind(document); document.createElement = function(tagName) { const ele = _originCreateA(tagName); if (tagName.toLowerCase() === 'a') { const _originSetAttr = ele.setAttribute.bind(ele); ele.setAttribute = function(attr, val) { if (attr === 'href' && val.startsWith('http')) { window._realDownloadUrl = val; } return _originSetAttr(attr, val); } } return ele; } // 执行原下载逻辑 _originDownload(vid); } """ driver.execute_script(hook_script) # 点击下载按钮 driver.find_element(By.CSS_SELECTOR, "a.down_t").click() # 等待JS执行完成,可替换为显式等待 time.sleep(1) real_url = driver.execute_script("return window._realDownloadUrl;") print(f"捕获到真实下载地址:{real_url}") driver.quit()
适配提示:如果原下载逻辑是通过window.open或location.href跳转触发,可将Hook点替换为重写window.open方法、location.href属性的setter,即可拦截到跳转的下载地址。
方案3:监听本地下载事件(兜底方案,不推荐)
如果上述两种方案因站点反爬限制无法生效,可配置Chrome的默认下载路径、关闭下载弹窗,监听下载目录内生成的临时下载文件对应的源请求地址。该方案会真实触发文件下载,占用带宽,仅作为兜底使用。
注意事项
- 若站点需要登录态,需先在Selenium内完成登录流程再触发下载,否则抓取到的会是登录跳转地址
- 下载链接匹配正则需要根据目标站点的实际链接格式调整,部分站点的临时签名CDN链接不带文件后缀,可通过接口路径关键字匹配
- 若下载按钮存在倒计时、权限校验等前置逻辑,需加显式等待,等按钮状态可点击后再触发点击,否则JS逻辑不会正常执行
内容的提问来源于stack exchange,提问作者Blog Khóa Học
相关产品推荐
相关产品推荐

