然后 , 在主函数中 , 通过写一个 for 循环 , 通过改变 pn 的值 , 获取每一页的评论数据 。 if __name__ == '__main__':for p。Pytho爬虫项目实战:采集B站《全职高手》20万条评论数据( 二 )。" />

Pytho爬虫项目实战:采集B站《全职高手》20万条评论数据( 二 )


;oid=11357166 --tt-darkmode-color: #999999;">然后 , 在主函数中 , 通过写一个 for 循环 , 通过改变 pn 的值 , 获取每一页的评论数据 。
if __name__ == '__main__':for page in range(0,9400):url = ';oid=11357166 --tt-darkmode-color: #999999;">3. 提取关键信息
通过 json 库对获取到的响应内容进行解析 , 然后提取我们需要的内容:楼层 , 用户名 , 性别 , 时间 , 评价 , 点赞数 , 回复数 。
import jsonimport time def parserHtml(html):'''功能:根据参数 html 给定的内存型 HTML 文件 , 尝试解析其结构 , 获取所需内容参数:html:类似文件的内存 HTML 文本对象'''s = json.loads(html)for i in range(20):comment = s['data']['replies'][i]# 楼层 , 用户名 , 性别 , 时间 , 评价 , 点赞数 , 回复数floor = comment['floor']username = comment['member']['uname']sex = comment['member']['sex']ctime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(comment['ctime']))content = comment['content']['message']likes = comment['like']rcounts = comment['rcount']print('--'+str(floor) + ':' + username + '('+sex+')' + ':'+ctime)print(content)print('like : '+ str(likes) + '' + 'replies : ' + str(rcounts))print('')部分运行结果如下: --204187:day可可铃(保密):2018-11-05 18:16:22太太又出本了 , 这次真的木钱了(′;ω;`)like : 1replies : 0--204186:长夜未央233(女):2018-11-05 16:24:5212区打卡like : 2replies : 0--204185:果然还是人渣一枚(男):2018-11-05 13:48:09貌似忘来了好几天like : 1replies : 1--204183:day可可铃(保密):2018-11-05 13:12:38要准备去学校了 , 万恶的期中考试( ′_ゝ`)like : 2replies : 0--204182:拾秋以叶(保密):2018-11-05 12:04:1911月5日打卡( ̄▽ ̄)like : 1replies : 0--204181:芝米士哒(女):2018-11-05 07:53:43这次是真的错过了一个亿[蛆音娘_扶额]like : 2replies : 14. 保存输出
我们把这些数据以 csv 的格式保存于本地 , 即完成了本次爬虫的全部任务 。 下面附上爬虫的全部代码 。
import requestsimport jsonimport time def fetchURL(url):'''功能:访问 url 的网页 , 获取网页内容并返回参数:url :目标网页的 url返回:目标网页的 html 内容'''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',}try:r = requests.get(url,headers=headers)r.raise_for_status()print(r.url)return r.textexcept requests.HTTPError as e:print(e)print("HTTPError")except requests.RequestException as e:print(e)except:print("Unknown Error !")def parserHtml(html):'''功能:根据参数 html 给定的内存型 HTML 文件 , 尝试解析其结构 , 获取所需内容参数:html:类似文件的内存 HTML 文本对象'''try:s = json.loads(html)except:print('error')commentlist = []hlist = []hlist.append("序号")hlist.append("名字")hlist.append("性别")hlist.append("时间")hlist.append("评论")hlist.append("点赞数")hlist.append("回复数")#commentlist.append(hlist)# 楼层 , 用户名 , 性别 , 时间 , 评价 , 点赞数 , 回复数for i in range(20):comment = s['data']['replies'][i]blist = []floor = comment['floor']username = comment['member']['uname']sex = comment['member']['sex']ctime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(comment['ctime']))content = comment['content']['message']likes = comment['like']rcounts = comment['rcount']blist.append(floor)blist.append(username)blist.append(sex)blist.append(ctime)blist.append(content)blist.append(likes)blist.append(rcounts)commentlist.append(blist)writePage(commentlist)print('---'*20) def writePage(urating):'''Function : To write the content of html into a local filehtml : The response contentfilename : the local filename to be used stored the response'''import pandas as pddataframe = pd.DataFrame(urating)dataframe.to_csv('Bilibili_comment5-1000条.csv', mode='a', index=False, sep=',', header=False)if __name__ == '__main__':for page in range(0,9400):url = ';oid=11357166 --tt-darkmode-color: #979797;">写在最后在爬取过程中 , 还是遇到了很多的小坑的 。
1. 请求的 url 不能直接用 , 需要对参数进行筛选整理后才能访问 。
2. 爬取过程其实并不顺利 , 因为如果爬取期间如果有用户发表评论 , 则请求返回的响应会为空导致程序出错 。 所以在实际爬取过程中 , 记录爬取的位置 , 以便出错之后从该位置继续爬 。 (并且 , 挑选深夜一两点这种发帖人数少的时间段 , 可以极大程度的减少程序出错的机率)
3. 爬取到的数据有多处不一致 , 其实这个不算是坑 , 不过这里还是讲一下 , 免得产生困惑 。
a. 就是评论区楼层只到了20多万 , 但是评论数量却有63万多条 , 这个不一致主要是由于B站的评论是可以回复的 , 回复的评论也会计算到总评论数里 。 我们这里只爬楼层的评论 , 而评论的回复则忽略 , 只统计回复数即可 。