一、爬取任务:
- 选择bilibili网站作为数据源,使用python语言编写程序,通过网络 爬虫技术抓取5000个视频的相关信息。
- 获取字段:UP主信息(用户名 、用户ID)、视频标题、视频上传时间、观看量、点赞量、弹幕数量、收藏数量、投币数量、视频时长等。
- 技术要求:使用requests库和beautifulsoup库提取数据。
二、实验过程
进入网页版B站“每周必看”栏目界面,按快捷键F12进入开发者模式,按下图所示获取信息。
三、代码部分:
导入需要的库
import datetime
import pandas as pd
import requests
摘取一个抓取响应标头cookie和请求标头信息,知道爬虫的小伙伴都知道有些参数是不需要的。
headers = {
'Referer': 'https://www.bilibili.com/v/popular/all/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/118.0.0.0'
'Safari/537.36 Edg/118.0.2088.76',
'Cookie': "#########"
}
url = 'https://api.bilibili.com/x/web-interface/popular?ps=20&pn=1&web_location=333.934&w_rid=2a0407fe9ff5a6771d69a8ffd365994f&wts=1716885729'
response = requests.get(url=url, headers=headers)
print(response)
打印结果为“<Response [200]>”说明成功get到该页面信息,接着我们可以在网页上找到数据保存格式为json格式,以字典形式逐渐提取需要的信息。
data = text.json()['data']['list']
for i in data:
data_time = str(datetime.datetime.fromtimestamp(i['pubdate'])).split(' ')[0] # 视频上传时间戳转换
item = {
'视频标题': i['title'],
# 正则表达式表示标题
# '视频标题': re.findall(r'<title>(.*?)</title>', i['title'])[0],
'视频封面': i['pic'],
'UP主用户名': i['owner']['name'],
'UP主ID': i['owner']['mid'],
'UP主用户头像': i['owner']['face'],
'视频时长': i['duration'],
'观看量': i['stat']['view'],
'点赞量': i['stat']['like'],
'弹幕量': i['stat']['danmaku'],
'收藏量': i['stat']['favorite'],
'投币量': i['stat']['coin'],
'上传时间': data_time,
'评论量': i['stat']['reply'],
'视频网址': 'https://www.bilibili.com/video/av' + str(i['aid'])
}
print(item)
然而,每一页的视频量仅仅只有30多个,接下来需要做的是获取多页视频。当点击下一页时可以发现,网址上的参数也有一定的变化,抓住这点,不难发现下一页的参数发生变化。其中只要改变number参数就可以得到下一期视频信息。
因此,只需要用for循环就可以实现。
for i in range(1, 10):
url = f'https://api.bilibili.com/x/web-interface/popular/series/one?number={i}'
最后,把数据全部存到一个列表里在保存为csv文件。
完整代码:
import datetime
import time
import pandas as pd
import requests
data_list = [] # 储列表
today = datetime.date.today()
def Get_data():
headers = {
'Referer': 'https://www.bilibili.com/v/popular/all/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/118.0.0.0'
'Safari/537.36 Edg/118.0.2088.76',
'Cookie': "###输入自己的Cookie#######"
}
for i in range(1, 10):
url = f'https://api.bilibili.com/x/web-interface/popular/series/one?number={i}'
response = requests.get(url=url, headers=headers)
time.sleep(2) # 延时2秒在下载下一页数据
# print(response)
# print(response.text)
Parse(response)
def Parse(text):
data = text.json()['data']['list']
for i in data:
data_time = str(datetime.datetime.fromtimestamp(i['pubdate'])).split(' ')[0] # 视频上传时间戳转换
item = {
'视频标题': i['title'],
'视频封面': i['pic'],
'UP主用户名': i['owner']['name'],
'UP主ID': i['owner']['mid'],
'UP主用户头像': i['owner']['face'],
'视频时长': i['duration'],
'观看量': i['stat']['view'],
'点赞量': i['stat']['like'],
'弹幕量': i['stat']['danmaku'],
'收藏量': i['stat']['favorite'],
'投币量': i['stat']['coin'],
'上传时间': data_time,
'评论量': i['stat']['reply'],
'视频网址': 'https://www.bilibili.com/video/av' + str(i['aid'])
}
data_list.append(item)
pd_data = pd.DataFrame(data_list)
pd_data.to_csv('data-%s.csv' % today, index=False)
print(item)
if __name__ == '__main__':
Get_data()
# print(list)
print("爬取成功..........")
小结
希望我的讲解,大家能够看懂。