下面我来为您详细讲解“使用python爬取B站千万级数据”的完整攻略。
引言
B站是一家知名的弹幕视频网站,拥有海量的视频资源。如果您是一名数据分析师,想要进行B站数据分析,那么获取B站数据就成为了必备的一部分。本文就是为大家介绍如何使用Python爬虫获取B站数据。
工具准备
本文涉及到以下工具:
- Python 3.x
- pymongo (Python的MongoDB驱动)
- requests (Python的HTTP请求库)
- BeautifulSoup4 (Python的HTML解析库)
- Chrome浏览器
获取B站数据的思路
B站提供了开放的API,但是这些API都需要申请key才能使用。如果数据量较小,我们可以向B站申请key。但是如果要获取海量的数据,那么多申请几个key也不太现实。由于这篇文章旨在爬取“千万级数据”,所以我们采用爬虫的方式获取数据。
爬取B站视频数据的思路如下:
- 首先获取视频的链接和ID
- 根据视频ID获取视频的详细信息
- 解析数据并保存到MongoDB数据库
爬取B站视频链接和ID
我们可以使用Chrome浏览器进行调试,找到B站的视频列表页,通过分析HTML代码找到有效的请求URL,然后使用requests库向URL发送请求。此处以B站哔哩哔哩2021年4月新番推荐为例,代码如下:
import requests
from bs4 import BeautifulSoup
url = "https://www.bilibili.com/anime/timeline/?spm_id_from=333.6.b_7072696d6172795f6d656e75.33#/2021/4/1/1/"
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")
for video in soup.select(".main-section > .section > .bangumi-list.bangumi-list-a > .bangumi-item"):
video_title = video.select_one(".title").text.strip()
video_url = video.select_one("a")["href"]
video_id = video.select_one("a")["data-id"]
print(video_id, video_title, video_url)
结果如下:
121246247 爆笑迷宫OVA:橙绮季 番外篇 /video/BV1E64y1c7nB/
121075255 吸血鬼马上死 第二季 /video/BV19v411t7H7/
121334208 睡觉·睡觉·睡觉 /video/BV1pL411a7fd/
121127266 异世界魔王与召唤少女的奴隶魔术Ω 第二季 /video/BV1JE411p7Le/
121145129 双重奏 /video/BV1JS4y1t79p/
121258372 木兰少女 /video/BV1gK4y1S7Ar/
121195313 86─不存在的战区─ 第2季 /video/BV1Zi4y1P7Wz/
121027045 魔法纪录 魔法少女小圆外传 第二季 /video/BV1kA411N78z/
121054021 末日时在做什么?有没有空?可以来拯救吗?第二季 /video/BV1vK4y1z7o7/
120147162 进击的巨人 The Final Season /video/BV1mk4y1J7sb/
我们可以看到,每一个视频都有一个唯一的ID,需要保存这个ID,后面会用到。
爬取B站视频详细信息
根据上一步获取的视频ID,我们可以向B站发送请求获取视频的详细信息。此处我们还是使用requests库发送请求,但是B站的API返回的数据是JSON格式的,我们需要使用Python内置的json库进行解析。最后解析出来数据后,我们将它保存到MongoDB数据库。代码如下:
import requests
import json
from pymongo import MongoClient
client = MongoClient() # 连接MongoDB
db = client["bilibili"]
def save_video_info(video_id, video_info):
"""
将视频信息保存到MongoDB
"""
db["videos"].update({"_id": video_id}, {"$set": video_info}, upsert=True)
def get_video_info(video_id):
"""
获取视频信息
"""
url = f"https://api.bilibili.com/x/web-interface/view?aid={video_id}"
r = requests.get(url)
if r.status_code == 200:
data = json.loads(r.text)["data"]
video_info = {
"_id": data["aid"], # 将视频ID作为MongoDB文档的唯一标识
"title": data["title"],
"description": data["desc"],
"view_count": data["view"],
"danmaku_count": data["danmaku"],
"like_count": data["like"],
"coin_count": data["coin"],
"favorite_count": data["favorite"],
"share_count": data["share"],
"category": data["tname"],
"tags": data["tag"]
}
save_video_info(video_id, video_info)
print(f"视频 {video_id} 信息获取成功")
else:
print(f"视频 {video_id} 信息获取失败,原因:{r.reason}")
注意,在爬取数据时,为了防止造成对B站服务器的过度压力,我们需要加入一些延迟操作。具体可以用time库的sleep函数来实现。
代码示例
下面我们以获取B站哔哩哔哩2021年4月新番推荐为例,来放一下完整代码:
import requests
import json
import time
from pymongo import MongoClient
from bs4 import BeautifulSoup
client = MongoClient() # 连接MongoDB
db = client["bilibili"]
def save_video_info(video_id, video_info):
"""
将视频信息保存到MongoDB
"""
db["videos"].update({"_id": video_id}, {"$set": video_info}, upsert=True)
def get_video_info(video_id):
"""
获取视频信息
"""
url = f"https://api.bilibili.com/x/web-interface/view?aid={video_id}"
r = requests.get(url)
if r.status_code == 200:
data = json.loads(r.text)["data"]
video_info = {
"_id": data["aid"], # 将视频ID作为MongoDB文档的唯一标识
"title": data["title"],
"description": data["desc"],
"view_count": data["view"],
"danmaku_count": data["danmaku"],
"like_count": data["like"],
"coin_count": data["coin"],
"favorite_count": data["favorite"],
"share_count": data["share"],
"category": data["tname"],
"tags": data["tag"]
}
save_video_info(video_id, video_info)
print(f"视频 {video_id} 信息获取成功")
else:
print(f"视频 {video_id} 信息获取失败,原因:{r.reason}")
def main():
url = "https://www.bilibili.com/anime/timeline/?spm_id_from=333.6.b_7072696d6172795f6d656e75.33#/2021/4/1/1/"
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")
for video in soup.select(".main-section > .section > .bangumi-list.bangumi-list-a > .bangumi-item"):
video_title = video.select_one(".title").text.strip()
video_url = video.select_one("a")["href"]
video_id = video.select_one("a")["data-id"]
print(video_id, video_title, video_url)
get_video_info(int(video_id)) # 获取视频详细信息
time.sleep(1) # 延迟1秒
if __name__ == "__main__":
main()
总结
到这里,我们就完成了使用Python爬虫获取B站数据的任务。当然,这只是个简单的示例,如果要获取更多、更详细的数据,我们需要考虑更多的细节问题,比如:防止被反爬,数据写入的优化等。希望本文能够对您有所帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用python爬取B站千万级数据 - Python技术站