python爬虫在线测试_Python爬虫的初步测试:在B站评论区爬虫,python,初试,取
本次爬取目标是最近看的一个很喜欢的描改手书的评论区,链接:
【幸运星】永远都想对战游戏的泉此方【永遠にゲームで対戦したいコナタン】
首先通过网页中f12使用网页开发工具找到评论区对应的html代码段:
目标爬取内容为每一个list-item reply-wrap下的con中的用户评论内容,用户名,回复时间,点赞数(暂定)。
首先检测能否获取html文件,简单对该网页的url:https://www.bilibili.com/video/BV1N5411x7rZ 使用request库的get方法,调用bs4库soup的lxml分析格式化,结果如下略
这时没发现有什么问题,继续根据标签属性讲需要的信息提取出来:
结果发现无论怎么样comment始终为空!!??返回回去debug,找到在
DivConTags = soup.find_all('div', attrs={'class': ' list-item reply-wrap'})
这步的时候就为空,没有找到标签div,class属性为list-item reply-wrap的元素。思考了许久回去发现再更之前的soup,甚至最开始的html中都没评论栏的元素。
查阅资料也没有得到明确的答案,个人猜测评论栏是额外加载的另一个域,没有直接保存在html文件中,需要每次打开的时候网页再次向服务器申请得到元素。
如何找到评论栏对应的html文件呢,可以由点击下一页的时候监测网页发出的请求找到类似的目标。
点击评论区下一页,发现网页url没有发生变化,说明b站评论区并不是通过url改变评论页数的。这里通过监视点击下一页按钮的时候网页对服务器发出的请求以及服务器的回答进行分析:
点击f12开发工具上方network栏
点击红点停止记录,再点击开始,待下方列表清空后点击下一页按钮,找到下方刷新出来的script文件:
可见在点击下一页后网页向服务器发出了Request URL这样的请求。
转到preview栏,分析服务器返回的内容:
这样,可以直观的看到评论栏中的内容。
但是,实际上https://api.bilibili.com/x/v2/reply?callback=jQuery17206650614708586977_1592139923724&jsonp=jsonp&pn=2&type=1&oid=455803935&sort=2&_=1592139955967,这个url我们并不能进入
服务器也拒绝我们的请求。
查询资料后,得知只需要删除该url一些额外的部分,就可以正常访问。最后得到的url如下:
https://api.bilibili.com/x/v2/reply?pn=2&type=1&oid=455803935&sort=2
其中pn=2代表评论的页数。这样我们就能很方便的进行爬取了。
接下来需要做的就是解析并获取需要的内容。这里选择尝试使用json库进行解析。
def get_html(url):
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}# 爬虫模拟访问信息
r = requests.get(url, timeout=30,headers=headers)
r.raise_for_status()
r.endcodding = 'utf-8'
return r.text
定义get_html函数获取html
将得到的html数据导入json在线解析工具,可以很清晰的看见其中数据的结构,方便之后解析获取:
json在线解析
解析结果如下:
可以很明显的看到想要找到的数据,接下来就是将数据取出,保存到列表中
def get_content(url):
'''
分析网页文件,整理信息,保存在列表变量中
'''
comments = []
# 首先,我们把需要爬取信息的网页下载到本地
html = get_html(url)
try:
s=json.loads(html)
except:
print("jsonload error")
num=len(s['data']['replies']) # 获取每页评论栏的数量
# print(num)
i=0
while i
comment=s['data']['replies'][i]# 获取每栏评论
InfoDict={} # 存储每组信息字典
InfoDict['Uname']=comment['member']['uname'] # 用户名
InfoDict['Like']=comment['like'] #点赞数
InfoDict['Content']=comment['content']['message'] # 评论内容
InfoDict['Time']=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(comment['ctime'])) # ctime格式的特殊处理?不太清楚具体原理
comments.append(InfoDict)
i=i+1
# print(comments)
return comments
检查一下结果是否是预期,打印出得到的comments:
正确。接下来只需要进行功能完善:数据格式输出、保存本地、翻页爬取。
完整代码如下:
'''
爬取B站评论区内容
'''
import requests
import time
from bs4 import BeautifulSoup
import json
# 首先我们写好抓取网页的函数
def get_html(url):
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}# 爬虫模拟访问信息
r = requests.get(url, timeout=30,headers=headers)
r.raise_for_status()
r.endcodding = 'utf-8'
#print(r.text)
return r.text
def get_content(url):
'''
分析网页文件,整理信息,保存在列表变量中
'''
comments = []
# 首先,我们把需要爬取信息的网页下载到本地
html = get_html(url)
try:
s=json.loads(html)
except:
print("jsonload error")
num=len(s['data']['replies']) # 获取每页评论栏的数量
# print(num)
i=0
while i
comment=s['data']['replies'][i]# 获取每栏评论
InfoDict={} # 存储每组信息字典
InfoDict['Uname']=comment['member']['uname'] # 用户名
InfoDict['Like']=comment['like'] #点赞数
InfoDict['Content']=comment['content']['message'] # 评论内容
InfoDict['Time']=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(comment['ctime'])) # ctime格式的特殊处理?不太清楚具体原理
comments.append(InfoDict)
i=i+1
# print(comments)
return comments
def Out2File(dict):
'''
将爬取到的文件写入到本地
保存到当前目录的 BiliBiliComments.txt文件中。
'''
with open('BiliBiliComments.txt', 'a+') as f:
i=0
for comment in dict:
i=i+1
try:
f.write('姓名:{}\t 点赞数:{}\t \n 评论内容:{}\t 评论时间:{}\t \n '.format(
comment['Uname'], comment['Like'], comment['Content'], comment['Time']))
f.write("-----------------\n")
except:
print("out2File error")
print('当前页面保存完成')
if __name__ == '__main__':
e=0
page=1
while e == 0 :
url = "https://api.bilibili.com/x/v2/reply?pn="+ str(page)+"&type=1&oid=455803935&sort=2"
try:
print()
# print(url)
content=get_content(url)
print("page:",page)
Out2File(content)
page=page+1
# 为了降低被封ip的风险,每爬20页便歇5秒。
if page%10 == 0:
time.sleep(5)
except:
e=1
一些需要注意的地方:
在编写的时候,发现在保存到本地的时候,总是会不报错直接退出,只写到第一页的第5个就停了。因此加了一个try/except抓取错误从而能进行下去(这点在爬取的时候也很重要,当因为一些什么意外爬虫被停下的时候需要它跳过这个错误继续进行,try/except块经常被使用)。
但是这样看下来有不少评论都因为写错误被过滤掉了,不够完善。
继续检查发现,在comments中,第5个出错的内容是:
{'Uname': '-狗眠-', 'Like': 99, 'Content': '精 准 推 送 。\n\n记得起来内容来源:\n幸运星 (主体内容)\n军曹keroro(宝可梦的形象)\n凉宫春日(团长臂章以及对话的头像)\n东方绯想天(加载界面以及ko之后的人物对话)\n\n何等,高技术力,修改也契合了作品的内容(´ε` )♡\n有老bili的味道了,呜', 'Time': '2020-06-01 12:41:00'}
编写一个额外的写程序尝试找到出错原因:
str="{'Uname': '-狗眠-', 'Like': 99, 'Content': '精 准 推 送 。\n\n记得起来内容来源:\n幸运星 (主体内容)\n军曹keroro(宝可梦的形象)\n凉宫春日(团长臂章以及对话的头像)\n东方绯想天(加载界面以及ko之后的人物对话)\n\n何等,高技术力,修改也契合了作品的内容(´ε` )♡\n有老bili的味道了,呜', 'Time': '2020-06-01 12:41:00'}"
with open("test.txt",'a+') as f:
f.write(str)
发现报错如下:
经过查阅资料得知,这大概是python默认编码的问题,需要打开文件的时候额外设置编码方式,修改代码为:
str="{'Uname': '-狗眠-', 'Like': 99, 'Content': '精 准 推 送 。\n\n记得起来内容来源:\n幸运星 (主体内容)\n军曹keroro(宝可梦的形象)\n凉宫春日(团长臂章以及对话的头像)\n东方绯想天(加载界面以及ko之后的人物对话)\n\n何等,高技术力,修改也契合了作品的内容(´ε` )♡\n有老bili的味道了,呜', 'Time': '2020-06-01 12:41:00'}"
with open("test.txt",'a+',encoding='utf-8') as f:
f.write(str)
将同样的修改应用到上面的代码,最终完整代码如下:
'''
爬取B站评论区内容
'''
import requests
import time
from bs4 import BeautifulSoup
import json
# 首先我们写好抓取网页的函数
def get_html(url):
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}# 爬虫模拟访问信息
r = requests.get(url, timeout=30,headers=headers)
r.raise_for_status()
r.endcodding = 'utf-8'
#print(r.text)
return r.text
def get_content(url):
'''
分析网页文件,整理信息,保存在列表变量中
'''
comments = []
# 首先,我们把需要爬取信息的网页下载到本地
html = get_html(url)
try:
s=json.loads(html)
except:
print("jsonload error")
num=len(s['data']['replies']) # 获取每页评论栏的数量
# print(num)
i=0
while i
comment=s['data']['replies'][i]# 获取每栏评论
InfoDict={} # 存储每组信息字典
InfoDict['Uname']=comment['member']['uname'] # 用户名
InfoDict['Like']=comment['like'] #点赞数
InfoDict['Content']=comment['content']['message'] # 评论内容
InfoDict['Time']=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(comment['ctime'])) # ctime格式的特殊处理?不太清楚具体原理
comments.append(InfoDict)
i=i+1
# print(comments)
return comments
def Out2File(dict):
'''
将爬取到的文件写入到本地
保存到当前目录的 BiliBiliComments.txt文件中。
'''
with open('BiliBiliComments.txt', 'a+',encoding='utf-8') as f:
i=0
for comment in dict:
i=i+1
try:
f.write('姓名:{}\t 点赞数:{}\t \n 评论内容:{}\t 评论时间:{}\t \n '.format(
comment['Uname'], comment['Like'], comment['Content'], comment['Time']))
f.write("-----------------\n")
except:
print("out2File error")
print('当前页面保存完成')
if __name__ == '__main__':
e=0
page=1
while e == 0 :
url = "https://api.bilibili.com/x/v2/reply?pn="+ str(page)+"&type=1&oid=455803935&sort=2"
try:
print()
# print(url)
content=get_content(url)
print("page:",page)
Out2File(content)
page=page+1
# 为了降低被封ip的风险,每爬20页便歇5秒。
if page%10 == 0:
time.sleep(5)
except:
e=1
运行结果:
没有在存储为文件时报错,正确
后续待添加的功能:添加交互,输入BV号得到目标评论区数据。
观察上面爬取的url。oid后的数字就是B站改版前的AV号:
https://api.bilibili.com/x/v2/reply?pn=2&type=1&
oid=455803935
&sort=2
BV号相当于只是加了个函数转换。
因此需要工具:
BV号转AV号
python爬虫在线测试_Python爬虫的初步测试:在B站评论区爬虫,python,初试,取相关推荐
- B站评论区抽奖[python]
Bili-Luckdog B站评论区抽奖工具 by - ALKEYSHENG 2020.5.21 第三方库requests Blog: i.2017.work Github项目: Bili-Lucky ...
- python爬取b站评论_用python 抓取B站视频评论,制作词云
python 作为爬虫利器,与其有很多强大的第三方库是分不开的,今天说的爬取B站的视频评论,其实重点在分析得到的评论化作嵌套的字典,在其中取出想要的内容.层层嵌套,眼花缭乱,分析时应细致!步骤分为以下 ...
- 微信朋友圈python广告投了多少钱_朋友圈广告的评论区,当代人的灌水BBS
记者 | 马越 编辑 | 牙韩翔 1 如果你最近几天都忍住没发过朋友圈,也没给任何人点赞评论,却冷不防多了个小红点提醒--没错,八成是又有人收到Python的广告了. 6张不明所以的图片,加上20个字 ...
- python异步封装_python中用协程(异步)实现map函数,爬虫也可以封装进去,
1.python中得函数map(),通过加延时发现,是单线程执行,有阻塞,实现如下: import time def A(a): time.sleep(0.5) c = a + 11 return c ...
- 在线运行python 怎么安全_Python安全开发与测试 - 安全牛课堂 - 领先的信息安全在线教育平台...
{ "i18nChapterName": "章", "i18nUnitName": "节", "i18nLes ...
- python自动化部署_Python特战班-企业级自动化项目全程部署实战课程 Python高级自动化开发项目课程...
(1)\\1.人人都爱列表:目录中文件数:1个 ├─Video_08-14_222522.wmv (2)\\10.定制数据对象(一):目录中文件数:5个 ├─james2.txt ├─julie2.t ...
- c向python注册函数_python如何调用C, 如何注册成C的回调函数(python后台程序常用方法)...
其实是python后台程序常用方法: C开发完成底层的功能,python直接把C当做python模块进行调用. 需要做两个工作: python能调用C语言的函数: python通过调用C函数,并注册p ...
- python 拼多多_python 拼多多_拼多多2018校招编程题汇总 Python实现
列表补全 在商城的某个位置有一个商品列表,该列表是由L1.L2两个子列表拼接而成.当用户浏览并翻页时,需要从列表L1.L2中获取商品进行展示.展示规则如下: 用户可以进行多次翻页,用offset表示用 ...
- python均线选股_python选股模型均线,已知股票数据,如何用Python绘制k线日对应数据...
Q1:已知股票数据,如何用Python绘制k线日对应数据 我没遇到过 只是自己写过 有点经验 先确定时间片 然后再把tick插入就行了 Q2:使用python实现ema(指数移动平均的计算) a = ...
最新文章
- ci框架 mysql_CodeIgniter (CI)框架中的数据库查询汇总
- lvs和keepalives
- spring boot integrated mybatis three ways!--转
- 我们可以无损放大一个Transformer模型吗?
- dataset_flickr8k.json与dataset_flickr30k.json的比较
- 主流or消亡?2016年大数据发展将何去何从
- B. 重载技术(overloading)
- Linux snmp 时间戳,linux snmp计数器汇总
- python语言开发环境搭建_Python开发环境搭建-Go语言中文社区
- 淄博联海城企业文件图纸数据信息透明加密系统
- stm32实验报告心得体会_STM32单片机红外遥控MP3实验报告
- 计算机专业英语容易挂科吗,大学英语专业容易挂科吗
- tRNAscan-SE使用说明
- 在github上托管属于自己的网页
- ESP32学习6:I2C总线
- 读取groundtruth_rect.txt并转为数组
- 物联网资产标记方法介绍
- 第13章 其他重要主题
- python创建httpserver,并处理get、post请求
- Java下载海康历史视频并合并转码