|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
之前学完爬虫和自己捣鼓了selenium这个自动化模块写的小程序。
现在回过来使用时发现不能使用了,查明发现b站现在似乎改使用bv号而不是av号。细微改动后还是可以使用滴。
注:如果多次爬取相同的个人空间视频,可能会被反爬虫检测到,可自行使用proxy。
import requests
from bs4 import BeautifulSoup
import json
from selenium import webdriver
import time
class Bilibili_danmu:
def __init__(self, start_url):
self.start_url = start_url
self.driver = webdriver.Chrome(r"D:\chromedriver.exe")
self.pagelist_url = 'https://api.bilibili.com/x/player/pagelist?bvid={}'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'}
self.danmu_url = 'https://api.bilibili.com/x/v1/dm/list.so?oid={}'
def get_space_url(self, start_url):
# 通过传入的视频获取up主的视频个人空间url地址
self.driver.get(start_url)
element = self.driver.find_element_by_xpath("//a[contains(@class,'username')]")
space_url = element.get_attribute('href')
return space_url
def get_aid_list(self, space_url):
# 获取个人空间一页(最多30个视频)的bv号列表
# bilibili将视频av号改成了bv号,此处的aid_list(原av号)即现在获取的bvid的列表
self.driver.get(space_url)
elements = self.driver.find_elements_by_xpath("//ul[contains(@class,'cube-list')]//li")
aid_list = []
for each in elements:
aid_list.append(each.get_attribute('data-aid'))
return aid_list
def get_cid_dict(self, aid):
# 此方法用来获取每个视频是否分p,分p的话获取每一个子视频的cid
pagelist_url = self.pagelist_url.format(aid)
response = requests.get(pagelist_url, headers=self.headers)
page_list = json.loads(response.content.decode())
cid_dict = {}
for each in page_list['data']:
cid_dict[each['cid']] = each['part']
return cid_dict
def save_danmu(self, cid_dict):
with open('danmu.txt', 'a', encoding='utf-8') as f:
for each in cid_dict:
f.write(cid_dict[each])
f.write(':\n\n')
danmu_url = self.danmu_url.format(each)
r = requests.get(danmu_url, headers=self.headers)
content = r.content.decode()
soup = BeautifulSoup(content, 'xml')
try:
result = (soup.find_all('d'))
for danmu in result:
f.write(danmu.string)
f.write('\n')
except:
f.write('\n')
def run(self):
# 1通过获取任何一个视频的网址,得到所属up个人空间视频页的url
space_url = self.get_space_url(self.start_url)
num = 1
while True:
url = space_url + ('/video?page={}'.format(str(num)))
print(url)
# 2提取视频页第一页的所有视频的aid地址,做成列表
aid_list = self.get_aid_list(url)
print(aid_list)
# 2.1 进入每一个aid对应的网址,获取是否当前视频有子视频,且提取所有子视频的对于弹幕xml文件。
for aid in aid_list:
cid_dict = self.get_cid_dict(aid)
# 2.2 将每个xml文件的弹幕保存到本地
self.save_danmu(cid_dict)
if len(aid_list) < 30:
# 如果当前个人空间页面的视频(aid)数量小于30,即已爬取到所有视频。停止循环
break
else:
# 3若视频页第一页所获取的列表个数等于30,进入第二页视频页。
# 3.1 循环2.1,2.2
num += 1
if __name__ == '__main__':
danmu = Bilibili_danmu('https://www.bilibili.com/video/BV1j4411c7ny')
danmu.run()
|
评分
-
查看全部评分
|