【Python爬虫常见错误】- AJAX动态加载数据爬取

爬虫必踩坑:页面明明有视频链接,为什么爬虫解析不到?(AJAX动态生成真相)

前言:刚入门爬虫的朋友,大概率会遇到这样的困惑------浏览器页面上能正常看到视频链接,甚至"检查"元素也能找到,可用requests请求页面、再用XPath/BS4解析时,却死活拿不到链接。结合自己的踩坑经历,今天就把这个核心知识点讲透,帮大家避开这个高频误区。

一、先明确核心问题:你看到的,≠ 爬虫看到的

很多新手会混淆两个关键概念,这也是踩坑的根源------浏览器"检查"(Elements)看到的页面,和网页"源代码"(View Page Source)完全不同,而爬虫拿到的,只是后者。

1. 浏览器"检查"(Elements):最终渲染后的页面

当你打开视频页面,按F12打开开发者工具,切换到「Elements」面板,看到的是浏览器执行完所有JS、加载完所有动态内容后的最终页面

这里面包含:

  • 原始HTML结构
  • CSS样式
  • JS动态生成的DOM元素(包括视频链接)
  • AJAX请求加载的所有数据

所以你在这里能看到视频链接,是完全正常的------这是浏览器"加工"后的结果。

2. 网页"源代码"(View Page Source):服务器返回的原始HTML

右键点击页面,选择「查看网页源代码」,能看到页面加载的所有信息(包括AJAX请求加载的数据)------这些数据是浏览器执行JS、发送AJAX后追加的,并非服务器第一次返回的原始内容;而爬虫用requests.get(url)只能获取这份"空壳"原始HTML,无法获取后续追加的内容,这就是爬虫爬不到视频链接的核心原因。

二、核心真相:视频链接是AJAX动态生成的,爬虫不"执行"JS

为什么页面上能看到视频链接,爬虫却拿不到?核心原因就在于:视频链接不是一开始就写在HTML里的,而是JS通过AJAX请求动态获取、再插入到页面中的,而爬虫(requests)不会执行JS,也不会主动发送AJAX请求。

完整流程拆解(一看就懂):

  1. 你用浏览器打开视频页面 → 浏览器向服务器发送请求;
  2. 服务器返回「空壳HTML」(没有视频链接,只有基础结构);
  3. 浏览器加载完空壳HTML后,自动执行页面中的JS代码;
  4. JS代码发送AJAX请求,向服务器获取视频相关数据(包含真实视频链接);
  5. 服务器返回视频数据,JS将视频链接插入到页面的DOM中;
  6. 你在浏览器「Elements」面板中看到视频链接,视频正常播放。

而爬虫的流程只有1-2步:请求页面 → 获取空壳HTML,没有后续的JS执行和AJAX请求,自然拿不到视频链接。

三、为什么XPath、BeautifulSoup解析不到?

很多人会习惯性用lxml的etree写XPath,或者用BeautifulSoup解析页面,结果一无所获,原因很简单:

XPath和BeautifulSoup,只能解析"静态HTML",不能执行JS,也不能识别JS中的内容

举个例子:视频链接藏在JS代码里,格式如下:

javascript 复制代码
// 这是JS代码,不是HTML标签
let videoInfo = {
  title: "爬虫教程",
  url: "https://xxx.com/xxx.mp4" // 真实视频链接
};

这种情况下,XPath 和 BS 4 只会解析 HTML 标签(比如<div>、<p>),根本不会去解析 JS 代码里的字符串,所以无论怎么写表达式,都找不到这个视频链接。

四、解决方案:3 种方法,轻松拿到动态视频链接

针对这种AJAX动态生成的视频链接,分享3种实用方法,从简单到复杂,可按需选择。

方法1:抓包找到AJAX接口(推荐,最高效)

这是最推荐的方法,不需要复杂操作,直接获取视频链接的源头,步骤如下:

  1. 打开视频页面,按F12打开开发者工具,切换到「Network」面板;(记得勾选保留日志)
  2. 点击「刷新」按钮,再点击播放视频,让浏览器触发AJAX请求;
  3. 在「Network」面板的搜索框中,输入关键词筛选(常用:mp4、m3u8、video、api、play);
  4. 找到对应的请求(一般是XHR类型),点击进入,查看「Response」(响应);
  5. 如果响应是JSON格式,里面大概率会有videoUrl、url等字段,直接提取即可;如果是直接返回视频链接,复制链接就能使用。

示例代码(获取接口返回的JSON数据,提取视频链接):

python 复制代码
import requests

# 抓包得到的AJAX接口地址
api_url = "https://xxx.com/api/getVideoInfo?id=123"
# 请求接口(注意:有些接口需要携带headers,模拟浏览器)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
}
response = requests.get(api_url, headers=headers)
# 解析JSON,提取视频链接
video_url = response.json()["data"]["url"]
print("真实视频链接:", video_url)

方法2:使用能执行JS的爬虫工具(适合复杂场景)

如果AJAX接口加密、难以抓包,可使用能模拟浏览器的工具,它们会自动执行JS、加载动态内容,相当于"用代码模拟人操作浏览器",常用工具:Selenium、Playwright。

  • 优势:不用抓包,直接获取浏览器渲染后的页面,就能用XPath/BS4解析视频链接;
  • 劣势:速度比requests慢,配置稍复杂。

方法3:正则表达式提取JS中的链接(兜底方案)

如果视频链接直接写在JS代码里(没有通过AJAX接口获取),可通过正则表达式,从JS字符串中匹配提取链接,示例代码:

python 复制代码
import requests
import re

# 请求视频页面,获取原始HTML(包含JS代码)
url = "https://xxx.com/video/123"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
}
response = requests.get(url, headers=headers)
# 用正则匹配JS中的视频链接(匹配规则根据实际JS代码调整)
# 示例:匹配 let videoUrl = "https://xxx.mp4" 中的链接
pattern = re.compile(r'videoUrl\s*=\s*["\'](.*?)["\']', re.S)
result = pattern.search(response.text)
if result:
    video_url = result.group(1)
    print("提取到的视频链接:", video_url)
else:
    print("未找到视频链接")

五、核心总结(必记)

  1. 页面上能看到的视频链接,是浏览器执行JS、发送AJAX后动态插入的,不是原始HTML自带的;

  2. requests爬虫只获取原始HTML,不执行JS、不发送AJAX,所以拿不到动态链接;

  3. XPath/BS4只能解析静态HTML,无法解析JS中的内容;

  4. 最优解:抓包找AJAX接口;复杂场景:用Selenium/Playwright;兜底:正则提取JS中的链接。

六、避坑提醒

  1. 不要混淆「Elements」和「网页源代码」,爬虫拿到的是后者;

  2. 遇到"页面有、爬虫无"的情况,优先考虑AJAX动态加载;

  3. 抓包时,记得携带headers(User-Agent等),避免被服务器识别为爬虫。

如果大家在实际操作中遇到抓包困难、正则匹配不到等问题,可以评论区留言,一起交流解决~

相关推荐
长和信泰光伏储能8 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂8 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study9 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境10 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境10 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd12310 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy123931021610 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb0011 小时前
一个项目带你入门AI应用开发01
python
05664611 小时前
Python康复训练——常用标准库
开发语言·python·学习
hyf32663311 小时前
泛程序:从零开始搭建稳定程序项目框架
运维·服务器·爬虫·百度·seo