### 思考过程:

好的,用户之前问过如何用Python嗅探网页中的m3u8链接,并且之前提供了几种方法,包括静态分析、Selenium动态处理和网络请求分析。现在用户的问题是:“动态加载内容的视频链接不使用selenium怎么实现?”。需要给出替代Selenium的方案。

首先,回顾之前的回答,用户已经知道Selenium的方法,但现在想避免使用它,可能因为Selenium资源占用高或配置复杂。需要寻找其他动态内容处理方法。

动态加载内容通常通过JavaScript异步请求获取,所以直接用requests可能不够,因为无法执行JS。这时候替代方案可能包括:

1. 使用Playwright,它支持异步和同步模式,资源消耗比Selenium低,且API更现代。

2. 使用requests直接模拟AJAX请求,找到视频数据的API端点,这需要分析网络请求,找到生成链接的接口。

3. 使用浏览器扩展或抓包工具(如Fiddler、Charles)获取真实请求,然后在代码中模拟。

4. 使用Pyppeteer或Puppeteer的Python版本,控制无头浏览器,但可能比Playwright更复杂。

用户可能希望用更轻量级的工具,所以重点放在Playwright和模拟AJAX请求上。同时需要考虑如何定位API接口,可能需要指导用户使用开发者工具分析网络请求,找到关键XHR/Fetch请求。

另外,用户可能遇到反爬机制,比如需要处理token、headers验证,或者动态生成的参数。这时候需要教他们如何提取必要的参数,使用requests.Session保持会话,或者处理Cookies。

还要注意示例代码的清晰度,确保用户能直接复制粘贴修改使用。同时提醒法律合规问题,避免侵权。

总结步骤:

1. 使用Playwright替代Selenium,示例代码。

2. 分析网络请求,直接模拟AJAX调用,获取m3u8链接。

3. 处理可能的动态参数和验证。

4. 使用其他工具如curl_cffi或requests-html渲染JS。

最后检查是否覆盖了用户需求,是否提供了足够的技术细节,同时避免使用Selenium。

----------

### 正式回答:

在不使用 Selenium 的前提下,动态加载内容的视频链接(如 m3u8)可以通过以下三种主流方案实现抓取,每种方案均附带完整代码示例和注意事项:

---

### **方案一:使用 Playwright 实现无头浏览器控制**

Playwright 是微软开发的现代化自动化工具,相比 Selenium 更轻量且支持异步操作。

```python

from playwright.sync_api import sync_playwright

def playwright_m3u8_crawler(url):

with sync_playwright() as p:

# 启动无头浏览器

browser = p.chromium.launch(headless=True)

page = browser.new_page()

# 监听所有网络请求

def handle_route(route, request):

if '.m3u8' in request.url:

print(f"[发现M3U8链接] {request.url}")

route.continue_()

page.route("**/*", handle_route)

# 加载页面并等待动态内容

page.goto(url)

page.wait_for_timeout(5000) # 等待5秒确保加载完成

# 获取页面内嵌的iframe或动态插入的script

iframes = page.query_selector_all("iframe")

for iframe in iframes:

src = iframe.get_attribute("src")

if src and ".m3u8" in src:

print(f"[iframe检测到] {src}")

browser.close()

# 使用示例

playwright_m3u8_crawler("https://example.com/video-page")

```

**优势特点**:

- 支持所有主流浏览器引擎(Chromium/Webkit/FF)

- 自带请求拦截功能,可精准捕获流媒体请求

- 异步 API 支持高并发抓取

---

### **方案二:直接模拟 AJAX 请求获取流媒体地址**

适用于视频链接通过独立接口获取的场景(需通过开发者工具定位 API)

```python

import requests

def ajax_api_crawler():

# 1. 访问主页面获取必要参数(如video_id)

main_url = "https://example.com/video-page"

headers = {

"User-Agent": "Mozilla/5.0",

"X-Requested-With": "XMLHttpRequest"

}

# 2. 发送预请求获取token或参数

pre_response = requests.get(main_url, headers=headers)

# 假设从响应中提取到video_id

video_id = "extracted_video_id"

# 3. 调用真实流媒体接口(需根据实际接口修改)

api_url = f"https://api.example.com/streaming?video_id={video_id}"

api_response = requests.get(api_url, headers=headers)

# 4. 解析返回的m3u8链接

if ".m3u8" in api_response.text:

print(f"原始M3U8地址: {api_response.json()['hls_url']}")

# 使用前需通过浏览器开发者工具 -> Network -> XHR 找到真实API

ajax_api_crawler()

```

**关键步骤**:

1. 使用浏览器开发者工具(F12)定位获取视频流的 API

2. 分析请求参数(可能包含加密 token 或时间戳)

3. 使用 requests 模拟完整请求链路

---

### **方案三:使用 requests-html 实现 JS 渲染**

轻量级方案,适合简单 JS 动态内容

```python

from requests_html import HTMLSession

def js_render_crawler(url):

session = HTMLSession()

r = session.get(url)

# 执行页面中的JavaScript

r.html.render(timeout=20, sleep=5)

# 查找所有脚本中的m3u8链接

for script in r.html.find("script"):

if script.text and ".m3u8" in script.text:

print(f"[脚本中发现] {script.text.split('.m3u8')[0]}.m3u8")

# 查找动态生成的video标签

video_tags = r.html.find("video")

for video in video_tags:

src = video.attrs.get("src", "")

if ".m3u8" in src:

print(f"[video标签] {src}")

# 使用示例

js_render_crawler("https://example.com/video-page")

```

**局限性**:

- 对复杂 SPA 页面支持有限

- 渲染性能低于 Playwright

- 需安装额外依赖(`pyppeteer`)

---

### **进阶技巧与注意事项**

1. **参数逆向工程**:

- 使用 `curl_cffi` 模拟浏览器指纹

- 使用 `browser_cookie3` 加载本地浏览器 Cookie

- 处理 JWT token 或加密参数(需配合 Pyppeteer 抓包分析)

2. **反爬应对策略**:

```python

# 使用代理IP示例

proxies = {

"http": "http://user:pass@proxy_ip:port",

"https": "http://user:pass@proxy_ip:port"

}

response = requests.get(url, proxies=proxies, timeout=10)

```

3. **m3u8 文件解析**:

```bash

# 使用ffmpeg下载并合并TS分片

ffmpeg -i "input.m3u8" -c copy output.mp4

```

4. **法律声明**:

> 请严格遵守《计算机软件保护条例》和《信息网络传播权保护条例》,仅将本技术用于合法授权内容或个人学习研究。

---

### **调试建议**

1. 使用 Chrome 开发者工具的 "Copy as cURL" 功能分析真实请求

2. 使用 Wireshark/Fiddler 抓包验证请求头完整性

3. 对于加密参数,可使用 Hook 技术监控 JS 函数调用

实际应用中建议优先采用方案二(API 直接调用),在无法获取接口时使用方案一(Playwright)。完整项目应结合日志记录、异常重试、速率控制等生产级特性。

Reply to this note

Please Login to reply.

Discussion

No replies yet.