爬取B站视频信息竟如此简单!!

追求一个人不能全靠【感动】。

准时早安晚安,风雨无阻地送三餐,并不会让对方喜欢上你,甚至有可能会厌恶你。

更加正确的做法是提升自己,让对方感受到你的【魅力】和【踏实】。

一个女人能爱上你,是爱你的人,而不是你的跪舔。

懂得嘘寒问暖,却毫无追求,认不清现实。

每天想着各种拌饭讨好她,虽然会让她开心,但并不会让她产生喜欢,更别谈爱上你。

这种男人并不会真正给对方带来【安全感】,即使对方说了【我爱你】,也不会太长久,舔到最后只会是一场空。

获取B站视频信息

今天为大家带来的实战项目是获取B站的视频信息数据。B站的视频信息数据主要有哪些呢?

  • 视频点赞数。
  • 视频投币数
  • 视频收藏数
  • 视频弹幕数
  • 视频播放时长
  • 视频发布时间

上面所说的几点内容就是视频的主要信息数据,我们的目的就是要将这些数据获取下来,并将数据保存到数据库中。

目标网页分析

我们爬取的数据是来自《观察者网》的所有视频的数据。

对于B站的每一个视频来说每一个视频都有一个AV号。

例如,我们点击第一个视频,在里面我们就可以看到视频的各个数据了,比如说:点赞数、投币数、收藏数、弹幕数、视频播放时长、视频发布时间。

image
image

看到了吗?视频的主要数据刚刚好是在网页中呈现出来的。

为了确保数据的准确与无误,我们需要点击Network,查看Response,看看里面是不是同样也包含此类数据,如果包含相同数据的话,说明数据确实包含在网页中,而不是通过js或者是Ajax异步加载出来的,当然我更希望是通过这两个手段去渲染数据,我也容易一点。

image

如上图所示,数据的确包含在网页中,也就是说可以通过Python正常的进行模拟访问并获取到我们想要的数据。

分析到这里,我就先把本次爬取的代码框架先写出来吧

# 获取网页信息
def get_html(url):
    pass

# 解析数据
def parse_html(html):
    pass

# 保存数据
def save_data(data):
    pass

获取网页信息

接下来就是将网页中我们需要的数据提取出来,这里我选择使用xpath来提取数据。

相对来说xpath比较简单,具体代码如下所示:

def parse_html(html):
    html = etree.HTML(html)
    title = html.xpath('//span[contains(@class, "tit")]/text()')[0]
    danmu = int(re.findall('\d+', html.xpath('//span[@class="dm"]/text()')[0])[0])
    times = html.xpath('//div[@class="video-data"]/span[3]/text()')[0]
    like = int(re.findall('\d+', html.xpath('//div[@class="ops"]/span[@class="like"]/@title')[0])[0])
    coin =int(re.findall('\d+', html.xpath('//div[@class="ops"]/span[2]/@title')[0])[0])
    collect = int(re.findall('\d+', html.xpath('//div[@class="ops"]/span[@class="collect"]/@title')[0])[0])
    return title, danmu, times, like, coin, collect

我对上面的代码做简单的说明:

title代表的是视频的标题;

danmu代表的是视频的弹幕数;

times代表的是视频发布时间;

like代表的是是点赞数;

coin代表的是投币数;

collect代表的是收藏数。

相信xpath语法不需要我再做任何的解释了吧。

认真阅读本文的小伙伴一定可以发现这边获取的数据还差一个,那就是视频时长。经过我的仔细查找之后也没有在响应中找到视频的播放时长,说实话,我当时瞬间懵了。

于是我返回上一级链接,

并将页面刷新,我很幸运,终于被我给找着了。

image-20210411003906545

在一个页面中一共有30个视频,视频的标题、ID号、播放时长都在这面了。从上图可以很明显的看出,数据是通过Ajax异步加载出来的json数据。

获取所有视频的链接与时间

通过对上面的分析,我已经有了大体的思路了。三十个视频的ID号都在这里了,这个是第一页视频的所有信息,首先我必须知道它所给的API在不同的页面会有什么变化。

# 第一页
https://api.bilibili.com/x/space/arc/search?mid=10330740&ps=30&tid=0&pn=1&keyword=&order=pubdate&jsonp=jsonp

# 第二页
https://api.bilibili.com/x/space/arc/search?mid=10330740&ps=30&tid=0&pn=2&keyword=&order=pubdate&jsonp=jsonp

# 第三页
https://api.bilibili.com/x/space/arc/search?mid=10330740&ps=30&tid=0&pn=3&keyword=&order=pubdate&jsonp=jsonp

变化的参数就是pn,随着页面的变化而变化。

因此,我在这里定义了两个方法,分别获取视频的链接与视频的播放时长。

具体代码如下:

# 获取1-10页的视频链接
def get_url():
    urls = []
    # times = []
    for page in range(1, 10):
        api_url = f'https://api.bilibili.com/x/space/arc/search?mid=10330740&ps=30&tid=0&pn={page}&keyword=&order=pubdate&jsonp=jsonp'
        data = requests.get(api_url, headers=headers).json()
        bvids = jsonpath.jsonpath(data, '$.data..vlist..bvid')
        time.sleep(0.5)
        url = ['https://www.bilibili.com/video/'+bvid for bvid in bvids]
        urls.extend(url)
    return urls

# 获取1-10页的视频播放时长
def get_length():
    times = []
    for page in range(1, 10):
        api_url = f'https://api.bilibili.com/x/space/arc/search?mid=10330740&ps=30&tid=0&pn={page}&keyword=&order=pubdate&jsonp=jsonp'
        data = requests.get(api_url, headers=headers).json()
        length = jsonpath.jsonpath(data, '$.data..vlist..length')
        times.extend(length)
        time.sleep(0.5)
    return times

修改获取网页信息代码

现在我是已经成功拿到视频的播放时长了,为了方便存储,因此,需要将在获取网页信息代码中来调用获取视频播放时长的方法即可。修改之后的代码如下:

def parse_html(html):
    global pages
    lengths = get_length()

    html = etree.HTML(html)
    title = html.xpath('//span[contains(@class, "tit")]/text()')[0]
    danmu = int(re.findall('\d+', html.xpath('//span[@class="dm"]/text()')[0])[0])
    times = html.xpath('//div[@class="video-data"]/span[3]/text()')[0]
    like = int(re.findall('\d+', html.xpath('//div[@class="ops"]/span[@class="like"]/@title')[0])[0])
    coin =int(re.findall('\d+', html.xpath('//div[@class="ops"]/span[2]/@title')[0])[0])
    collect = int(re.findall('\d+', html.xpath('//div[@class="ops"]/span[@class="collect"]/@title')[0])[0])

    return title, danmu, times, like, coin, collect, lengths[pages]

因为,获取的播放时长,是放在一个列表中,因此,我在定义了一个全局变量:pages,当我调用完save_data()方法之后使pages加1即可。

这个pages其实表示的是每个视频的播放时长。

保存数据

本次保存的数据是放在MySQL数据库中,具体代码如下所示:

def save_data(data):
    host = 'localhost'
    user = 'root'
    password = '密码'
    port = 3306
    db = pymysql.connect(host=host, user=user, password=password, port=port, db='bilibli')
    cursor = db.cursor()
    sql = 'insert into data3(title, danmu, vediotime, likecount, coin, collect, vediolength) values (%s, %s, %s, %s, %s, %s, %s)'
    print(data)

    try:
        cursor.execute(sql, data)
        db.commit()
        print('插入成功')
    except Exception as e:
        print(e)
        db.rollback()
        print('插入失败')

注意在此之前必须要先创建好数据库bilibli和数据表data3,然后再调用上面的方法,将数据保存至数据库中。

image

本篇文章只做简单的爬虫知识,不做数据分析。

以本文为例,各位小伙伴们可以去爬取你们喜欢的UP主的视频详细数据,可以多爬取一个数据,比如说播放量,做B站视频Top100的数据分析,来巩固自己的爬虫知识和技巧,顺便再学习了简单的数据可视化知识。

最后

别人的建议只是参考答案,人生没有标准答案。

你不需要去抄别人,逼自己和别人一模一样,写你觉得对的答案就好。

看完文章,觉得对你有帮助的,可以给啃书君点个【在看】,我会继续努力,和你们一起成长前进。

文章的每一个字都是我用心敲出来的,只希望对得起每一位关注我的人。

点个【在看】,让我知道你们也在为人生【拼尽全力】。

我是啃书君,一个专注于学习的人,你懂的越多,你不懂的越多。更多精彩内容,我们下期再见!

respect

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,976评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,249评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,449评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,433评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,460评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,132评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,721评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,641评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,180评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,267评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,408评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,076评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,767评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,255评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,386评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,764评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,413评论 2 358

推荐阅读更多精彩内容