如何用Selenium提取JS注入JSON中的m3u8视频链接?
解决Selenium获取JS注入的M3U8链接问题
嘿,我来帮你搞定这个问题!你遇到的情况很常见——动态加载的JSON数据不会直接出现在初始的page_source里,因为它是页面加载后通过JavaScript注入或者异步请求获取的。下面给你两种靠谱的解决方案,结合你的现有代码来调整:
方法一:从浏览器全局变量中提取数据
很多网站会把视频相关的JSON数据挂载到window全局对象上(比如window.__INITIAL_STATE__、window.videoInfo这类命名),你可以直接通过Selenium执行JavaScript来获取这些数据。
步骤 & 代码修改:
- 登录后等待页面完全加载(确保JavaScript已经执行并注入了数据)
- 执行JS脚本提取全局变量中的JSON
- 解析JSON找到M3U8链接
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import json driver = webdriver.Chrome() driver.get('https://ed.team/clase/49/464/2199') # 你的登录代码 usuario = driver.find_element_by_name("email") usuario.clear() usuario.send_keys("你的邮箱") contra = driver.find_element_by_name("password") contra.clear() contra.send_keys("你的密码") driver.find_element_by_css_selector("#__next > main > section > form > div:nth-child(3) > input").click() # 等待页面加载完成(这里以等待视频元素出现为例,你可以根据实际页面调整选择器) wait = WebDriverWait(driver, 15) wait.until(EC.presence_of_element_located((By.TAG_NAME, "video"))) # 提取全局变量中的视频数据(需要你先在浏览器控制台确认变量名!) # 打开F12控制台,输入window后找包含视频信息的变量,比如window.videoData video_data = driver.execute_script("return window.videoData;") if video_data: # 如果返回的是字符串就解析成JSON,否则直接用 video_json = json.loads(video_data) if isinstance(video_data, str) else video_data # 根据实际JSON结构提取M3U8链接,这里只是示例,你要对应网站的结构调整 m3u8_link = video_json.get("stream", {}).get("hls", {}).get("url") if m3u8_link: print(f"成功获取M3U8链接:{m3u8_link}") else: print("找到视频数据,但没找到M3U8字段,请检查JSON结构") else: print("没找到对应的全局变量,试试第二种方法") driver.quit()
方法二:拦截网络请求获取JSON数据
如果数据是通过异步XHR/fetch请求加载的,你可以用Selenium的Chrome DevTools API拦截网络请求,直接获取返回的JSON响应。
步骤 & 代码修改:
- 启用Chrome的网络监听功能
- 登录并访问页面,监听所有网络响应
- 筛选出包含视频数据的请求,提取响应体中的M3U8链接
from selenium import webdriver import json import time driver = webdriver.Chrome() # 启用Chrome DevTools的网络监听 driver.execute_cdp_cmd('Network.enable', {}) # 存储找到的M3U8链接 target_m3u8 = None # 定义响应处理函数 def handle_network_response(response): global target_m3u8 response_info = response['params']['response'] # 筛选请求:比如URL包含"video"或"api",且响应是JSON类型 if 'video' in response_info['url'] and response_info['mimeType'] == 'application/json': # 获取响应体 response_body = driver.execute_cdp_cmd( 'Network.getResponseBody', {'requestId': response['params']['requestId']} ) try: data = json.loads(response_body['body']) # 根据实际JSON结构提取M3U8,这里是示例 target_m3u8 = data.get('video', {}).get('stream', {}).get('m3u8') except Exception as e: print(f"解析响应出错:{e}") # 添加监听事件 driver.add_cdp_listener('Network.responseReceived', handle_network_response) # 执行登录和访问页面 driver.get('https://ed.team/clase/49/464/2199') usuario = driver.find_element_by_name("email") usuario.clear() usuario.send_keys("你的邮箱") contra = driver.find_element_by_name("password") contra.clear() contra.send_keys("你的密码") driver.find_element_by_css_selector("#__next > main > section > form > div:nth-child(3) > input").click() # 等待请求完成(也可以用WebDriverWait等待target_m3u8不为None) time.sleep(6) if target_m3u8: print(f"成功获取M3U8链接:{target_m3u8}") else: print("没找到对应的视频请求,请调整URL筛选条件") # 关闭网络监听 driver.execute_cdp_cmd('Network.disable', {}) driver.quit()
关键提示:
- 确认全局变量/请求URL:打开Chrome开发者工具(F12),在
Console标签里输入window找视频相关变量;在Network标签筛选XHR/fetch,找返回视频JSON的请求,记录URL特征和响应结构。 - 等待时间调整:根据网站加载速度调整
WebDriverWait的超时时间,避免因加载慢导致获取失败。 - 反爬注意:如果网站检测无头模式,暂时不要开启
headless;可以添加自定义User-Agent模拟真实浏览器。
内容的提问来源于stack exchange,提问作者SGarcia
相关产品推荐
相关产品推荐

