【Python】使用Python根据BV号爬取对应B站视频下的所有评论(包括评论下的回复)
本文写于2020-4-27,当你阅读到本文的时候如果因为下列原因导致本文代码无法正常工作,本人概不负责。
- B站的页面和API接口的变动
- B站为页面和API加入了反爬虫机制,或者对请求首部有了新的要求
- Python版本的变动和标准库的调整
- BeautifulSoup4的变动
使用到的库
- 【第三方库】:BeautifulSoup4
- 【标准库】: urlpib.request中的Request对象和urlopen函数
- 【标准库】: json和gzip,用于解码从网络获得的数据
爬取思路
- 根据BV号,获取页面
www.bilibili.com/video/{BV}
,从页面的meta
标签中可以获得视频对应的AV号和评论条数(包括评论的回复)这两个信息。 - 使用B站的API获取视频的评论,即从
api.bilibili.com/x/v2/reply
获取视频的评论,得到的是JSON格式的数据。 - 使用B站的API获取评论的回复,即从
api.bilibili.com/x/v2/reply/reply
获取评论的回复,得到的是JSON格式的数据。
(一) 通过BV号获取AV号和评论数
通过页面www.bilibili.com/video/{BV}
可以获得一个原始页面,需要注意的是用urlopen
打开这个页面时需要添加好头部字段,否则会返回HTTP403。
第一个问题:最初我是用chrome内核的Edge打开B站页面时,发现浏览器添加的头部字段中有一部分只能在HTTP2.0中使用,如下图所示:
经过查看文档和一番搜索,我发现urlopen只支持HTTP1.1,而且似乎没有成熟的能够进行HTTP2.0请求的第三方库,然后我尝试使用火狐打开页面,发现火狐添加的头部字段中没有只能在HTTP2.0中使用的部分,所以我复制了一份火狐的头部字段在代码中使用。
代码如下:
video_url = 'https://www.bilibili.com/video/' + bv
headers = {
'Host': 'www.bilibili.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Cookie': '',
'Upgrade-Insecure-Requests': '1',
'Cache-Control': 'max-age=0',
'TE': 'Trailers',
}
rep = Request(url=video_url, headers=headers) # 建立一个Request对象
html_response = urlopen(rep) # type: HTTPResponse
第二个问题:www.bilibili.com/video/{BV}
返回的页面是通过gzip编码的,需要使用Python内置的gzip模块进行解码,解码后得到的是byte字符串,需要调用其decode方法转换成utf-8编码的字符串。
代码如下:
html_content = gzip.decompress(html_response.read()).decode(encoding='utf-8')
至此,我们可以按照正常的方式初始化BeautifulSoup对象,查看获得的页面可以发现,视频的AV号和评论数记录在以下两个meta
标签中:
<meta data-vue-meta="true" property="og:url" content=