上一篇传送门:初学Python爬虫:爬取B站某个详情页的所有标题

经过了一个星期的学习,本学渣又来啦。

这次的准备:
urllib、time、random、xlwt、gzip、io、json模块!

如果掌握好了前面的东西,似乎B站可以翻个底朝天了?

既然如此…让我来康♂康♂

咦?扒不出来?明明我是按照之前的方法来爬视频的啊?

urllib.error.HTTPError: HTTP Error 403: Forbidden

给了我这么一个错误,让我百度一下…找到了!

【爬虫 | 报错】urllib.error.HTTPError: HTTP Error 403: Forbidden

找视频可不是白找的,网站需要验证你是个人,不能非法访问!

如果有恶意爬虫爬过来,一下子几十万条数据扒下去,网站都要崩溃啦!

所以这就是所谓的反爬虫措施,目前通过查找资料,我明白了两个:

1、没有合适的契约(缺失用户信息),拒绝。

2、太贪吃(访问速度过快),拒绝。

第二点似乎说会所ip,因为后面加了应对措施,所以不太清楚,也不敢去试啊。

博主温馨提醒:爬虫千万个,安全第一个;爬取不规范,亲人两行泪。

解决第一个问题就是按链接中的方法,在F12开发者界面中,找到对应位置的信息,补充进去,我的是这样子的:

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
req = urllib.request.Request(url=url0, headers=headers)
page=urllib.request.urlopen(req).read()

然后困扰很久的就是乱码问题了:你会发现,这样的确能把代码扒下来,但它是乱码状态,而且伴随编码越界的错误。起初我以为是解码问题,用的不是utf-8…

但不是的,查看网页编码方式的通用方法介绍了怎么查看。

哦,utf-8,没错…

初学Python爬虫:爬取B站前x个视频年份、投币数与播放量

终于找到了!

爬虫初学报错:UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0x8b in position 1: i

加入gzip将代码解压…

ok,你就得到了需要的代码。

那么上面第二点怎么办呢?引入休眠,据说加随机或许会好一点?

time.sleep(3 + random.random())

还有还有!一些视频被删除了,怎么办?

通过对网页代码的观察,会发现删掉的视频会出现error-body的字段,直接查找就可以辨别啦!

数据总算是扒下来了…什么?!硬币数和播放数呢?

这是json的魔法了。json可以用于展示变化的数据,在网页文件中是不储存的。

解铃还须系铃人,B站视频,上!

Python爬虫,网页抓json数据包详细教程,爬虫必备技能

成功了!运用json的loads()直接转成字典!

全代码如下:

import urllib.request
import time
import random
import xlwt
import gzip
from io import BytesIO
import json


#目标:爬取B站av1-1110视频时间、弹幕数、投币数,形成表格

#初始化并创建一个工作簿
book = xlwt.Workbook()
#创建一个名为sheetname的表单
sheet = book.add_sheet('结果')

str0 = 'l-con'
str1 = 'r-con'
strerr='error-body'

sheet.write(0,0,"视频时间")
sheet.write(0,1,"弹幕数")
sheet.write(0,2,"投币数")

#url0="https://www.bilibili.com/video/av1"
#headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
#req = urllib.request.Request(url=url0, headers=headers)
#page=urllib.request.urlopen(req).read()
#time.sleep(3+random.random())
jjj = 1

for urlll in range(1,1111):
    url0 = "https://www.bilibili.com/video/av" + str(urlll)
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
    req = urllib.request.Request(url=url0, headers=headers)
    page=urllib.request.urlopen(req).read()
    buff = BytesIO(page)
    f = gzip.GzipFile(fileobj=buff)
    getHtml = f.read().decode('utf-8')
    time.sleep(3 + random.random())
    if strerr in getHtml:
        continue
    content = getHtml.partition(str0)[2]
    content = content.partition(str1)[0]
    title_list = []
    num1 = content.index('<time>', 0)+6
    num2 = content.index('</time>', num1)
    title_list.append(content[num1:num2])
    #这里统计时间
    url1="https://api.bilibili.com/x/web-interface/archive/stat?aid=" + str(urlll)
    req1 = urllib.request.Request(url=url1, headers=headers)
    page1 = urllib.request.urlopen(req1).read()
    resu = json.loads(page1)
    inresu=resu['data']
    title_list.append(inresu['danmaku'])
    #这里统计弹幕数
    title_list.append(inresu['coin'])
    #这里统计投币数
    kkk = 0
    for i in title_list:
        sheet.write(jjj, kkk, i)
        kkk = kkk + 1
    jjj=jjj+1

#将工作簿以bookname命名并保存
book.save('wewantto2.xls')


注意,这个程序要跑很久,请自行修改for的range值…
现在的这个直接复制粘贴的话,要跑大约一个小时…吧?

得出结果如下:

时间上,前面1110个视频从2009-06-26 15:11:36到2012-10-15 23:57:11,横跨三年(当然你会发现前面的视频很多的时间是错乱的)
初学Python爬虫:爬取B站前x个视频年份、投币数与播放量
最高播放量292263(截止到爬取时间),其中播放量少于100的有275个,挖远古巨坟的人请加油!

而在投币量方面:

初学Python爬虫:爬取B站前x个视频年份、投币数与播放量

over,收工!

相关文章:

  • 2022-12-23
  • 2021-08-22
  • 2022-12-23
  • 2021-11-20
  • 2021-12-19
  • 2022-01-17
  • 2022-12-23
  • 2021-08-25
猜你喜欢
  • 2022-01-02
  • 2021-11-12
  • 2022-12-23
  • 2021-11-23
  • 2021-12-19
  • 2022-01-28
  • 2021-09-15
相关资源
相似解决方案