b站视频排行榜爬取爬取b站排行榜
如果您有SEO优化、网站建设需求请致电:18510193015
#分析:
观察图一可发现,每个视频的 info 都在 li 标签内,我们能用 xpath 获取。在此,我期望得到视频的封面、播放量、综合得分以及视频链接。除封面外,其余信息均可通过此方式获取,后来我在另一个链接中找到了封面的相关信息,后续会讲到。
我们点击视频链接进入播放页,按 F12 后点击 network,让视频播放,会看到许多以 m4s 结尾的 xhr 文件不断刷新。
我们点击视频链接进入播放页,按 F12 后点击 network,让视频播放,会看到许多以 m4s 结尾的 xhr 文件不断刷新。
由此可推断视频是由一段段 m4s 文件组合而成。我复制其中一个链接打开,如图三所示。
由此可推断视频是由一段段 m4s 文件组合而成。我复制其中一个链接打开,如图三所示。
此时我们思考,即便能获取这个文件,又该如何获取这一个个链接呢?找了许久未找到,那就换种思路,是否有一个完整的视频链接,它会存于何处呢?最后终于发现,它其实隐藏在一开始的 elements 中,在此搜索 window,会出现图四的情况。
此时我们思考,即便能获取这个文件,又该如何获取这一个个链接呢?找了许久未找到,那就换种思路,是否有一个完整的视频链接,它会存于何处呢?最后终于发现,它其实隐藏在一开始的 elements 中,在此搜索 window,会出现图四的情况。
打开页面源码查看,感觉它像是 json 文件,这里可用正则获取。分析如下:
打开页面源码查看,感觉它像是 json 文件,这里可用正则获取。分析如下:
print('===================================')
print('===================================')
dic 是我们得到的 json 数据,经过层层剖析,发现视频与音频是两个分开的文件,我们可以下载后合成。分析结果如下:accept_description 指的是视频画质,accept_quality 指的是视频画质对应的 id,我没有会员,所以最高能获取高清 1080 的画质视频,视频文件在 video 的 baseUrl 中,音频文件在 audio 的 baseUrl。同时,我尝试将图一红线的那一串字符复制,在视频链接的 elements 中搜寻,居然找到了,打开链接就是原先封面,在其他视频链接中尝试,得到的也都是视频封面,用正则即可获取。
我们的分析完成了,接下来上代码。
我们的分析完成了,接下来上代码。
代码:
1:引入库
import re
from random import randint
import requests
from lxml import etree
from time import sleep
import json
import os
2:建立 session,共享 cookie
print (' 建立 session')
session = requests.Session()
base_headers = { }
session.get(url = base_url, headers = base_headers)
sleep(randint(3, 5))
3: 爬取视频排行榜:(在这里我觉得 headers 加上 referer 非常重要,referer 即上一级网页链接)
print (' 爬取排行榜视频 ')
dic = { }
leaderboard_headers = { }
response = session.get(url = leaderboard_url, headers = leaderboard_headers)
sleep(randint(3, 5))
content = response.content
html = etree.HTML(content)
info_list = html.xpath('//ul/li')
name = li.xpath('div/div/a/text()')
score = li.xpath ('div/div/div/div/text ()') + ' 综合得分'
play_volume = li.xpath('div/div/div/span/text()').strip()
list =
dic = list
在这里我把视频的 name 作为字典的 key,而视频链接、综合得分、播放量放在列表里,list 作为字典的 value。
4:在爬取时,有时 session 无法使用,就用 try 尝试,如果 session 可以,就不用 except,不行的话,就用 request.get 请求,别忘了加入 cookie。我在爬取时,把视频链接与音频链接放入一个列表,再把这个列表放入前面的列表中。
print (' 视频爬取 ')
video_headers = { }
num = 0
video_url = dic
response = session.get(url = video_url, headers = video_headers)
video_headers = 自己的 cookie,
response = requests.get(url = video_url, headers = video_headers)
text = response.text
img_url = re.search(r'metadata - vue - meta = "true" itemprop = "image" content = "(.?)"', text).group(1)
img_url = re.search(r'metadata - vue - meta = "true" itemprop = "image" content = "(.?)"', text).group(1)
dic.append(img_url)
dic.append(img_url)
data = re.search(r'playinfo = (.?) / scriptscript', text).group(1)
data = json.loads(data)
time = data
minute = int(time) // 60
second = int(time) % 60
video_url = data
audio_url = data
list =
dic.append(list)
print(video_url)
print(audio_url)
print (' 视频时长 {} 分 {} 秒 '.format (minute, second))
time = data // 1000
minute = int(time) // 60
second = int(time) % 60
video_url = data
list =
dic.append(list)
print (' 视频时长 {} 分 {} 秒 '.format (minute, second))
5:视频音频下载
都有这两个,然后我添加进去成功了
print (' 下载 ')
headers = { }
bool = mkdir(path)
video_path = path + '_video.mp4'
audio_path = path + '_audio.mp4'
save_path = path + '{}.mp4'.format(num)
info_path = path + '{}.text'.format(num)
img_path = path + '{}.png'.format(num)
img_path = path + '{}.png'.format(num)
num += 1
print ('{} 视频开始爬取 '.format (i))
response = requests.get(dic, headers = headers)
print(response.status_code)
f.write(response.content)
print ('{} 视频爬取完成 '.format (i))
print ('{} 音频开始爬取 '.format (i))
response = requests.get(dic, headers = headers)
f.write(response.content)
print ('{} 音频爬取完成 '.format (i))
6:封面下载与 info 保存:
headers = { }
response = requests.get(url = dic, headers = headers)
f.write(response.content)
info = i + '\n' + dic + '\n' + dic
f.write(info)
7:视频合成
先要视频合成必须以管理员身份运行编辑器,我用的是 pycharm,还有就是编辑器编码要变成’gbk’,不能’utf - 8’
cmd = r'ffmpeg - i {} - i {} - acodec copy - vcodec copy {}'.format(video_path, audio_path, save_path)
p = os.popen(cmd)
全部代码:
import re
from random import randint
import requests
from lxml import etree
from time import sleep
import json
import os
print (' 建立 session')
session = requests.Session()
base_headers = { }
session.get(url = base_url, headers = base_headers)
sleep(randint(3, 5))
print (' 爬取排行榜视频 ')
dic = { }
leaderboard_headers = { }
response = session.get(url = leaderboard_url, headers = leaderboard_headers)
sleep(randint(3, 5))
content = response.content
html = etree.HTML(content)
info_list = html.xpath('//ul/li')
name = li.xpath('div/div/a/text()')
score = li.xpath ('div/div/div/div/text ()') + ' 综合得分'
play_volume = li.xpath('div/div/div/span/text()').strip()
list =
dic = list
print (' 视频爬取 ')
video_headers = { }
num = 0
video_url = dic
response = session.get(url = video_url, headers = video_headers)
video_headers = 自己的 cookie
response = requests.get(url = video_url, headers = video_headers)
text = response.text
img_url = re.search(r'metadata - vue - meta = "true" itemprop = "image" content = "(.?)"', text).group(1)
img_url = re.search(r'metadata - vue - meta = "true" itemprop = "image" content = "(.?)"', text).group(1)
dic.append(img_url)
dic.append(img_url)
data = re.search(r'playinfo = (.?) / scriptscript', text).group(1)
data = json.loads(data)
time = data
minute = int(time) // 60
second = int(time) % 60
video_url = data
audio_url = data
list =
dic.append(list)
time = data // 1000
minute = int(time) // 60
second = int(time) % 60
video_url = data
list =
dic.append(list)
print (' 下载视频音频 ')
headers = { }
bool = mkdir(path)
video_path = path + '_video.mp4'
audio_path = path + '_audio.mp4'
save_path = path + '{}.mp4'.format(num)
info_path = path + '{}.text'.format(num)
img_path = path + '{}.png'.format(num)
img_path = path + '{}.png'.format(num)
print ('{} 视频开始爬取 '.format (i))
response = requests.get(dic, headers = headers)
print(response.status_code)
f.write(response.content)
print ('{} 视频爬取完成 '.format (i))
print ('{} 音频开始爬取 '.format (i))
response = requests.get(dic, headers = headers)
f.write(response.content)
print ('{} 音频爬取完成 '.format (i))
headers = { }
response = requests.get(url = dic, headers = headers)
f.write(response.content)
info = i + '\n' + dic + '\n' + dic
f.write(info)
composite(video_path, audio_path, save_path)
sleep(randint(5, 8))
print ('{} 已经被爬取 '.format (i))
num = num + 1
folder = os.path.exists(path)
os.makedirs(path)
return 1
return 0
cmd = r'ffmpeg - i {} - i {} - acodec copy - vcodec copy {}'.format(video_path, audio_path, save_path)
p = os.popen(cmd)
get_link_and_img()
get_link_and_img()
这里面的下载视频与音频还有封面,以及合成视频音频可以再 def 一个函数,看起来比较好看,容易读。
这里我把字典的对应表示出来 key:]。另外可以看到我里面有 sleep,为什么呢?因为我们要遵循一定的规则。好了,这一期爬虫就到这里为止,如果你有不懂得地方。