CSDN个人主页: 高智商白痴
原文地址: https://blog.csdn.net/qq_44700693/article/details/109124334?utm_source=app
导入
前段时间我已经将B站的爬取方法做了一个总结:Python爬虫:哔哩哔哩(bilibili)视频下载。
这一次,我将继续分享 AcFun 视频网站的解析,其实相对于B站,A站的反爬机制更为简单:
单个短视频
获取视频的信息
为了能够方便的解析与说明,就肯定会拿一个例子来才好的哇:
【仙女UP特辑】AcFun Family Party ——成都站(今天又是
lsp的一天呢~~)
直接在浏览器端打开并抓包该链接发现,在 XHR 的数据下,第一条(又或者某一次)的请求就加载了视频的真实请求链接:
虽然本身仅仅是一个 m3u8 文件,不过我们还是有办法处理的,我们在此之前先必须要找到该文件的亲亲贵是从哪里发出来的,又或者能够在哪里找到这个链接。
在找遍了 XHR 数据无果后,我决定去看一看网页源码:
当我用 m3u8 文件的请求链接在网页源码中搜索后发现,链接就出现在源码中:
因为在源码中是以 JSON 数据存放的:
所以我们需要将数据格式化,方便我们进行数据提取:
虽然我将该数据格式化以后发现,有一个字段的值居然也是一个 JSON 数据的格式,所以我们再对第二层的 JSON 数据进行格式化后可以看到以下信息:
对于未登录时的状态,即使网页端不能直接播放,但是 “ 后台 ” 早已经给我们准备好了播放链接(B站则是加载当前账户或着未登录时能观看的最大清晰度),所以我们可以在未登陆的情况下 白嫖 超高清资源~~
class m3u8_url():
def __init__(self, f_url):
self.url = f_url
def get_m3u8(self):
global flag, qua, rel_path
html = requests.get(self.url, headers=headers).text
first_json = json.loads(re.findall('window.pageInfo = window.*? = (.*?)};', html)[0] + '}', strict=False)
name = first_json['title'].strip().replace("|",'')
video_info = json.loads(first_json['currentVideoInfo']['ksPlayJson'], strict=False)['adaptationSet'][0]['representation']
为了后续能够选择清晰度,所以我还进行了清晰度的爬取:
for quality in video_info: # 清晰度
num += 1
Label[num] = quality['qualityLabel']
print(Label)
choice = int(input("请选择清晰度: "))
通过m3u8文件地址下载视频
到此,我们已经可以拿到视频的 m3u8 文件的地址,那么现在就来开始解决之前遗留的一个小问题:如何通过 m3u8 文件下载视频?
首先,我们拿到一个 m3u8 文件来作为案例:
为了方便,在这里我手动的写了一个 m3u8 文件来作为例子。
我们知道,在 m3u8 文件中的视频链接都是 .ts 的分段格式,所以我们必须要先想办法将所有的 .ts 链接都拿出来,并且加上前缀,拼装成视频的真实完整的链接:(在这里假设视频原前缀为 https://www.acfun.cn/)
urls=[] # 用于保存视频的分段链接
def get_ts_urls():
with open('123.m3u8',"r") as file:
lines = file.readlines()
for line in lines:
if '.ts' in line:
print("https://www.acfun.cn/"+line)
通过以上方法,我们就可以通过 m3u8 文件来获取每一段的视频链接了,接下来,我们再将下载的功能进行完善:
下载的基本思路还是和我以前的一篇文章的思路一样:Python爬虫:用最普通的方法爬取ts文件并合成为mp4格式
class Download():
urls = [] # 用于保存视频的分段链接
def __init__(self, name, m3u8_url, path):
'''
:param name: 视频名
:param m3u8_url: 视频的 m3u8文件 地址
:param path: 下载地址
'''
self.video_name = name
self.path = path
self.f_url = str(m3u8_url).split('hls/')[0] + 'hls/'
with open(self.path + '/{}.m3u8'.format(self.video_name), 'wb')as f:
f.write(requests.get(m3u8_url, headers={
'user-agent': 'Chrome/84.0.4147.135'}).content)
def get_ts_urls(self):
with open(self.path + '/{}.m3u8'.format(self.video_name), "r") as file:
lines = file.readlines()
for line in lines:
if '.ts' in line:
self.urls.append(self.f_url + line.replace('\n', ''))
def start_download(self):
self.get_ts_urls()
for url in tqdm(self.urls, desc=