Python:爬取爱奇艺(网站)视频弹幕——以《爱情公寓5》为例

 

本文以作者亲身经历为逻辑线讲述爬取过程,方便读者举一反三。

一、明确爬取内容

1. 首先我们打开《爱情公寓5》第一集视频,广告之后,打开控制台(F12),使用 Ctrl+Shift+C 指令,获取 Html 中弹幕元素:

Ctrl+Shift+C 指令
Html中的弹幕元素

2. 我们看到该部分内容是动态更新的,<div>标签的 status 属性表明了当前元素的播放状态,设想直接请求网页获取Html后进行解析来获取弹幕是不可行的,故我们从网页与服务器的交互进行下手。理所当然,我们想到了控制台的 Network 功能,点开 Netwrok 后,使用 Ctrl+R 指令,重新加载网页:

Ctrl+R 指令
网页与服务器交互文件

3. 在茫茫文件中,我们通过过滤器试着查找一下 bullet ,我们可以看到有以下几个文件:

过滤器
与bullet有关的文件

4. 我们观察一下每个 Request URL :

Request URL:
https://cmts.iqiyi.com/bullet/40/00/11298454000_300_5.z?rn=0.41964474120625517&business=danmu&is_iqiyi=true&is_video_page=true&tvid=11298454000&albumid=212447801&categoryid=2&qypid=01010021010000000000

我们对 URL 解析发现,请求的主要部分为:

# https://cmts.iqiyi.com/bullet/tv_id[-4:-2]/tv_id[-2:]/tv_id_300_x.z
# https://cmts.iqiyi.com/bullet/视频编号的倒数4、3位/视频编号的倒数2、1位/视频编号_300_序号.z
# 弹幕文件每5分钟(300秒)向服务器请求一次,故每集弹幕文件数量等于视频时间除以300之后向上取整,实际编程时这里可以简单处理

该文件为.z文件,故我们得先解压后才能看到实际内容。


二、代码编程

1. 获取《爱情公寓5》36集的视频编号(tv_id):

  • tv_id.py
import requests
import json


def get_tv_id(aid):
    # tv_id列表
    tv_id_list = []

    for page in range(1, 3):
        url = 'https://pcw-api.iqiyi.com/albums/album/avlistinfo?aid=' \
              + aid + '&page='\
              + str(page) + '&size=30'

        # 请求网页内容
        res = requests.get(url).text

        res_json = json.loads(res)

        # 视频列表
        move_list = res_json['data']['epsodelist']
        for j in move_list:
            tv_id_list.append(j['tvId'])

    return tv_id_list


if __name__ == '__main__':
    # 节目id
    my_aid = '212447801'
    my_tv_id_list = get_tv_id(my_aid)

2. 爬取并解析弹幕:

  • bullet.py
import zlib
import requests

tv_id_module = __import__('tv_id')


def get_bullet(tv_id):
    for page in range(1, 17):
        # https://cmts.iqiyi.com/bullet/tv_id[-4:-2]/tv_id[-2:]/tv_id_300_x.z
        url = 'https://cmts.iqiyi.com/bullet/'\
              + tv_id[-4:-2] + '/'\
              + tv_id[-2:] + '/'\
              + tv_id + '_300_'\
              + str(page) + '.z'
        print(url)

        # 请求弹幕压缩文件
        res = requests.get(url).content
        res_byte = bytearray(res)
        try:
            xml = zlib.decompress(res_byte).decode('utf-8')

            # 保存路径
            path = '../data/' + tv_id + '_300_' + str(page) + '.xml'
            with open(path, 'w', encoding='utf-8') as f:
                f.write(xml)
        except:
            return


if __name__ == '__main__':
    # 节目id
    my_aid = '212447801'
    # tv_id列表
    my_tv_id_list = tv_id_module.get_tv_id(my_aid)
    for i in my_tv_id_list:
        get_bullet(str(i))

代码已上传到本人 GitHubhttps://github.com/Ambitioner-c/iqiyi_bullet.git

发布了25 篇原创文章 · 获赞 37 · 访问量 2940

猜你喜欢

转载自blog.csdn.net/qq_41297934/article/details/104463851