用Python爬取Bilibili上二次元妹子的视频

本文详细介绍使用Fiddler抓包结合Python与Requests库实现Bilibili视频爬取的全过程,包括视频包抓取、Headers参数分析、视频下载及UP主主页视频信息爬取。

点击上方“编程派”,选择设为“设为星标”

优质文章,第一时间送达!

作者:Mike_Shine

来源:https://urlify.cn/2qyMBb

一直想爬取BiliBili的视频,无奈一直没有去研究一下。

最近,在旭哥的指点之下,用了Fiddler抓包,抓到了一直期待的视频包,完成了下载。

下面写一下我做这个爬虫的过程。

# 相关依赖  :Fiddler+Python3 + Requests

下面看一下我做这个爬虫的具体步骤:

1. 进入某个具体视频的页面抓取视频包测试。

进入这个页面:https://www.bilibili.com/video/av26019104,如下图所示。点击播放按钮。

可以看到Fiddler已经抓到了很多包。别着急,现在还没有视频包出现。由于需要时间下载,所以具体视频包会过一会才能弹出来。

过大概一两分钟,就会看到这个包,如下图。可以清楚的看到这个是Flv形式的视频流的包,看这个包的大小也可以看出来,是相当的大。

下面分析一下这个包的具体参数。点击上图红色圈圈那个“Raw",会弹出下面这个窗口

可以看到是一个Get请求,请求的url和Headers都很清楚。

这时候就可以实验一下,来写一小段代码测试一下是否可以通过requests.get()方法来下载视频。

#######################################################################import requests
with open("D:\video\bilibili.mp4") as f:  f.write(requests.get(url, headers = headers, verify = False).content)       #这里的Verify=False是跳过证书认证  print("下载完成") # 这里只是写了核心部分,headers和url没有写,直接copy过来就好了,# 注意Url前面要加Host.   真正的请求地址是http://主机Host地址/upgcx.......############################################################################

可以看到如果你运行这段代码,已经可以把视频下载到了本地。

这里你可以多试几个视频,可能会发现,有些视频按照抓包得到的Headers,请求之后只能Get到一部分视频,比如视频8M,你Get到只有2M。你去看一下Headers就会发现,他多了一个Range参数。把这个删除掉,就可以下载了。

经过我的实验,所有视频请求的Headers格式都可以统一为下图这样。里面有2个参数哈。

1.host,主机名,就是从你爬出来的URL中正则出来的host

2. 视频标号。

2. 获取请求Headers参数和请求源URL:

要找URL,可以看一下URL中的内容,里面的hfa=xxxxxxxx和hfb=xxxxxxx应该是加密的?这可怎么办。这时候用Fiddler,从抓来的包里搜索一下这两个参数,肯定藏在某个包里。用CTRL + F 输入hfa 搜索。可以看到包含HFA关键字的包都被找出来了。

进去一看,其实包含在网页源代码的包,也就是说URL中的参数包含在网页源代码里。

回到最初的那个视频页面,看一下网页源代码。搜索一下URL。

惊喜的发现,其实整个URL都在网页源码里。这岂不是太简单了。

不过需要注意的是,这个URL中含有的hfa等加密部分是会动态变化的。所以在最终脚本的代码结构中,需要拿一个URL,及时用来做get请求。下载完成之后再拿下一个URL。

我之前就犯过这样的错,由于URL过期,导致部分视频下载不到。

3. 从UP主的主页爬取所有视频的信息(视频编号,标题)。

在之前的实验之上,现在只要有视频编号,我们就可以下载到对应的视频了。所以接下来要做的工作就是从Up主的主页来获取所有的视频信息。

访问某个Up主的主页

点击圈圈的更多,可以进入所有视频的页面。

这时候看Filddler抓包的结果,看到这个json包,里面包含了本页所有视频的信息。

同样,看一下包头。如下图

也做一下实验,可以发现Cookie是不必须的参数。

同之前下载视频的Get方法,同样可以Get到这个Json包。然后就可以把内容通过Json解析的语句拿出来。

这里我并没有做翻页的工作,而是直接请求了100个视频。想做翻页的同学,加一点代码就好了。

回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,立即获取主页君与小伙伴一起翻译的《Think Python 2e》电子版
回复关键词「入门资料」,立即获取主页君整理的 10 本 Python 入门书的电子版
回复关键词「m」,立即获取Python精选优质文章合集
回复关键词「book 数字」,将数字替换成 0 及以上数字,有惊喜好礼哦~
题图:pexels,CC0 授权。

好文章,我在看❤️

### 实现哔哩哔哩评论分页数据抓取 为了实现哔哩哔哩评论的分页数据抓取,可以按照以下方法操作: #### 构造评论页面URL 通常情况下,B站视频的评论页面URL格式为`https://www.bilibili.com/video/avXXXXXX/#reply`,其中`avXXXXXX`代表视频的AV号。通过拼接URL的方式能够轻松构造出目标评论页面的链接[^1]。 ```python base_url = "https://api.bilibili.com/x/v2/reply/main" params = { 'jsonp': 'jsonp', 'next': '{page}', # 占位符,用于后续替换具体的页码 'type': '1', # 类型参数,对于视频来说固定为'1' 'oid': 'av_number_here', # 需要替换成实际的目标视频AV号 'mode': '', 'plat': '1', } ``` #### 发送HTTP请求并解析响应内容 利用Python中的requests库向上述构建好的API接口发起GET请求,并处理返回的结果以提取所需的信息。需要注意的是,在发送请求前应确保已配置好有效的Cookie信息以便绕过反爬虫机制[^2]。 ```python import requests from urllib.parse import urlencode def fetch_comments(page, av_num): url = base_url + '?' + urlencode({**params, 'next': str(page), 'oid': str(av_num)}) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Cookie': 'your_cookie_string_here' # 替换为你自己的cookie字符串 } response = requests.get(url=url, headers=headers).json() replies = [] if not isinstance(response['data'], dict): return [] for reply in response["data"]["replies"]: user_name = reply["member"]["uname"] content = reply["content"]["message"] likes = reply["like"] replies.append({ "username": user_name, "comment": content, "likes": likes }) return replies ``` 此函数接受两个参数:一个是当前访问的页数(`page`);另一个是要查询的具体视频ID(`av_num`)。它会返回一个包含用户名、评论正文及其点赞数量的对象列表作为结果集的一部分。 #### 多线程或多进程加速抓取效率 考虑到网络延迟等因素可能影响整体性能表现,建议采用多线程或异步IO模型来进行并发请求提交,从而提高程序执行速度。例如使用concurrent.futures模块下的ThreadPoolExecutor类来管理多个工作线程池实例完成任务调度。 ```python from concurrent.futures import ThreadPoolExecutor, as_completed max_workers = 8 # 设置最大并发量 pages_to_fetch = range(1, total_pages+1) with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = {executor.submit(fetch_comments, page, target_av_id): page for page in pages_to_fetch} for future in as_completed(futures): try: comments_batch = future.result(timeout=30) save_data(comments_batch) # 假设有一个save_data函数用来保存每一批次的数据 except Exception as e: print(e) ``` 以上代码片段展示了如何创建一定规模的工作线程池去同时加载不同页码对应的评论记录,并将它们逐一存储起来供进一步分析处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值