使用Python获取爱奇艺电视剧弹幕数据的示例代码


Posted in Python onJanuary 12, 2021

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

以下文章来源于数据STUDIO,作者龙哥带你飞

Python分析抖音用户行为数据视频讲解地址

https://www.bilibili.com/video/BV1yp4y1q7ZC/

数据获取是数据分析中的重要的一步,数据获取的途径多种多样,在这个信息爆炸的时代,数据获取的代价也是越来越小。因此如此,仍然有很多小伙伴们无法如何获取有用信息。此处以最近的热播排行榜第一名的《流金岁月》为例,手把手教你如何获取爱奇艺电视剧弹幕数据。

使用Python获取爱奇艺电视剧弹幕数据的示例代码

寻找弹幕信息

爱奇艺的弹幕数据已通过.z形式的压缩文件存在,先通过以下步骤找到弹幕url, tvid列表,再获取压缩文件。利用工具对获取的压缩文件进行解压,处理,存储及分析。

使用Python获取爱奇艺电视剧弹幕数据的示例代码

绝对,实行多页爬取,需要分析url规律,利用url规律循环请求并获取所需内容。

此弹幕文件url地址为
https://cmts.iqiyi.com/bullet/93/00/6024766870349300_300_1.z
其中tvid = 6024766870349300

url普适形式为
url ='https:
//cmts.iqiyi.com/bullet/{}/{}/{}_300_{}.z'其中第一个与第二个花括号内容是tvid后3、4位,,后1、2位。第三个花括号为tvid。第四个花括号为子文件序号,其不是一个无穷大的数,会根据不同的电视剧有不同的最大数。

使用Python获取爱奇艺电视剧弹幕数据的示例代码

获取弹幕文件

可以利用浏览器通过url直接请求,并获取结果。

使用Python获取爱奇艺电视剧弹幕数据的示例代码

输入网址可获取弹幕内容的压缩文件文件。

使用Python获取爱奇艺电视剧弹幕数据的示例代码

利用解压/压缩包zlib对下载下来的压缩文件进行解压查看。

import zlib
from bs4 import BeautifulSoup
with open(r"C:\Users\HP\Downloads\6024766870349300_300_10.z", 'rb') as fin:
 content = fin.read()
btArr = bytearray(content)
xml=zlib.decompress(btArr).decode('utf-8')
bs = BeautifulSoup(xml,"xml")
bs

输出

使用Python获取爱奇艺电视剧弹幕数据的示例代码

因此tvid只要获得就能轻松获取该电视剧的弹幕文件数据。

import zlib
from bs4 import BeautifulSoup
import pandas as pd
import requests
def get_data(tv_name,tv_id):
 """
 获取每集的tvid
 :param tv_name: 集数,第1集、第2集...
 :param tv_id: 每集的tvid
 :return: DataFrame, 最终的数据
 """
 base_url = 'https://cmts.iqiyi.com/bullet/{}/{}/{}_300_{}.z'
 # 新建一个只有表头的DataFrame
 head_data = pd.DataFrame(columns=['uid','contentsId','contents','likeCount'])
 for i in range(1,20):
 url = base_url.format(tv_id[-4:-2],tv_id[-2:],tv_id,i)
 print(url)
 res = requests.get(url)
 if res.status_code == 200:
  btArr = bytearray(res.content) 
  xml=zlib.decompress(btArr).decode('utf-8') # 解压压缩文件
  bs = BeautifulSoup(xml,"xml") # BeautifulSoup网页解析
  data = pd.DataFrame(columns=['uid','contentsId','contents','likeCount'])
  data['uid'] = [i.text for i in bs.findAll('uid')]
  data['contentsId'] = [i.text for i in bs.findAll('contentId')]
  data['contents'] = [i.text for i in bs.findAll('content')]
  data['likeCount'] = [i.text for i in bs.findAll('likeCount')]
 else:
  break
 head_data = pd.concat([head_data,data],ignore_index = True)
 head_data['tv_name']= tv_name
 return head_data

获取tvid

上文已通过tvid获取到了弹幕文件数据,那么如何获取tvid又变成了一个问题。莫急,我们继续分析。直接Ctrl + F搜索tvid

使用Python获取爱奇艺电视剧弹幕数据的示例代码

因此可以直接从返回结果中通过正则表达式获取tvid。

from requests_html import HTMLSession, UserAgent
from bs4 import BeautifulSoup
import re
def get_tvid(url):
 """
 获取每集的tvid
 :param url: 请求网址
 :return: str, 每集的tvid
 """
 session = HTMLSession() #创建HTML会话对象
 user_agent = UserAgent().random #创建随机请求头
 header = {"User-Agent": user_agent}
 res = session.get(url, headers=header)
 res.encoding='utf-8'
 bs = BeautifulSoup(res.text,"html.parser")
 pattern =re.compile(".*?tvid.*?(\d{16}).*?") # 定义正则表达式
 text_list = bs.find_all(text=pattern) # 通过正则表达式获取内容
 for t in range(len(text_list)):
 res_list = pattern.findall(text_list[t])
 if not res_list:
  pass
 else:
  tvid = res_list[0]
 return tvid

由此问题tvid。来每一集都有一个tvid,有多少集电视剧就可以获取多少个tvid。那么问题又来了:获取tvid时,是通过url发送请求,从返回结果中获取。而每一集的url又该如何获取呢。

获取每集url

通过元素选择工具定位到集数选择信息。通过硒模拟浏览器获取动态加载信息。

使用Python获取爱奇艺电视剧弹幕数据的示例代码

有小伙伴会说,可以直接直接从返回内容中获取此href网址啊,你可以自己动手尝试下。

云朵君尝试后得到的结果是href="javascript:void(0);" rel="external nofollow" ,因此解决这一问题的方法之一是运用硒模拟浏览器获取js动态加载信息。

def get_javascript0_links(url, class_name, class_name_father, sleep_time=0.02):
 """
 Selenium模拟用户点击爬取url
 :param url: 目标页面
 :param class_name: 模拟点击的类
 :param class_name_father: 模拟点击的类,此类为class_name的父类
 :param sleep_time: 留给页面后退的时间
 :return: list, 点击class为class_name进去的超链接
 """

 def wait(locator, timeout=15):
 """等到元素加载完成"""
 WebDriverWait(driver, timeout).until(EC.presence_of_element_located(locator))

 options = Options()
# options.add_argument("--headless") # 无界面,若你需要查看界面内容,可以将此行注释掉
 driver = webdriver.Chrome(options=options)
 driver.get(url)

 locator = (By.CLASS_NAME, class_name)
 wait(locator)
 element = driver.find_elements_by_class_name(class_name_father)
 elements = driver.find_elements_by_class_name(class_name)
 link = []
 linkNum = len(elements)
 for j in range(len(element)):
 wait(locator)
 driver.execute_script("arguments[0].click();", element[j]) # 模拟用户点击
 for i in range(linkNum):
  print(i)
  wait(locator)
  elements = driver.find_elements_by_class_name(class_name) # 再次获取元素,预防StaleElementReferenceException
  driver.execute_script("arguments[0].click();", elements[i]) # 模拟用户点击
  time.sleep(sleep_time)
  link.append(driver.current_url)
  time.sleep(sleep_time)
  driver.back()
 driver.quit()
 return link

if __name__ == "__main__":
 url = "https://www.iqiyi.com/v_1meaw5kgh3s.html"
 class_name = "qy-episode-num"
 link = get_javascript0_links(url, class_name, class_name_father="tab-bar")
 for i, _link in enumerate(link):
 print(i, _link)

主函数

接下来通过主函数将所有步骤串起。

def main(sleep_second=0.02):
 url = "https://www.iqiyi.com/v_1meaw5kgh3s.html"
 class_name = "select-item"
 class_name_father = "bar-li"
 links = get_javascript0_links(url, class_name, class_name_father)
 head_data = pd.DataFrame(columns=['tv_name','uid','contentsId','contents','likeCount'])
 for num, link in enumerate(links):
 tv_name = f"第{num+1}集"
 tv_id = get_tvid(url=link)
 data = get_data(tv_name,tv_id)
 head_data = pd.concat([head_data,data],ignore_index = True)
 time.sleep(sleep_second)
 return head_data

获取到的数据结果如下:

>>> data = main()
>>> data.info()
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 246716 entries, 0 to 246715
Data columns (total 5 columns):
 # Column Non-Null Count Dtype 
--- ------ -------------- ----- 
 0 tv_name 246716 non-null object
 1 uid  246716 non-null object
 2 contentsId 246716 non-null object
 3 contents 246716 non-null object
 4 likeCount 246716 non-null object
dtypes: object(5)
memory usage: 9.4+ MB
"""
>>> data.sample(10)

使用Python获取爱奇艺电视剧弹幕数据的示例代码

词云图先分词

运用中文分词库jieba分词,并去除撤销词。

def get_cut_words(content_series):
 """
 :param content_series: 需要分词的内容
 :return: list, 点击class为class_name进去的超链接
 """
 # 读入停用词表
 import jieba 
 stop_words = [] 
 with open("stop_words.txt", 'r', encoding='utf-8') as f:
 lines = f.readlines()
 for line in lines:
  stop_words.append(line.strip())
 # 添加关键词
 my_words = ['倪妮', '刘诗诗', '锁锁', '蒋三岁', '陈道明'] 
 for i in my_words:
 jieba.add_word(i) 
 # 自定义停用词
 my_stop_words = ['哈哈哈','哈哈哈哈', '真的'] 
 stop_words.extend(my_stop_words)  
 # 分词
 word_num = jieba.lcut(content_series.str.cat(sep='。'), cut_all=False)
 word_num_selected = [i for i in word_num if i not in stop_words and len(i)>=2] # 条件筛选
 
 return word_num_selected

后画图

运用升级版词云图库stylecloud可视化弹幕结果。

import stylecloud
from IPython.display import Image 
text1 = get_cut_words(content_series=data.contents)
stylecloud.gen_stylecloud(text=' '.join(text1), collocations=False,
    font_path=r'‪C:\Windows\Fonts\msyh.ttc',
    icon_name='fas fa-rocket',size=400,
    output_name='流金岁月-词云.png')
Image(filename='流金岁月-词云.png')

到此这篇关于使用Python获取爱奇艺电视剧弹幕数据的示例代码的文章就介绍到这了,更多相关Python获取爱奇艺电视剧弹幕数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
使用Python获取Linux系统的各种信息
Jul 10 Python
web.py在模板中输出美元符号的方法
Aug 26 Python
利用python获取Ping结果示例代码
Jul 06 Python
Django后台获取前端post上传的文件方法
May 28 Python
用python做游戏的细节详解
Jun 25 Python
详解将Pandas中的DataFrame类型转换成Numpy中array类型的三种方法
Jul 06 Python
基于Python安装pyecharts所遇的问题及解决方法
Aug 12 Python
Pycharm 字体大小调整设置的方法实现
Sep 27 Python
使用python制作一个解压缩软件
Nov 13 Python
Python numpy.zero() 初始化矩阵实例
Nov 27 Python
使用 Supervisor 监控 Python3 进程方式
Dec 05 Python
Python assert关键字原理及实例解析
Dec 13 Python
将不规则的Python多维数组拉平到一维的方法实现
Jan 11 #Python
python用分数表示矩阵的方法实例
Jan 11 #Python
termux中matplotlib无法显示中文问题的解决方法
Jan 11 #Python
完美解决Pycharm中matplotlib画图中文乱码问题
Jan 11 #Python
Python脚本调试工具安装过程
Jan 11 #Python
装上这 14 个插件后,PyCharm 真的是无敌的存在
Jan 11 #Python
Jupyter Notebook 远程访问配置详解
Jan 11 #Python
You might like
phpmyadmin 访问被拒绝的真实原因
2009/06/15 PHP
最新最全PHP生成制作验证码代码详解(推荐)
2016/06/12 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
总结PHP内存释放以及垃圾回收
2018/03/29 PHP
菜鸟学习JavaScript小实验之函数引用
2010/11/17 Javascript
js查错流程归纳
2012/05/04 Javascript
原生js实现给指定元素的后面追加内容
2013/04/10 Javascript
JS+CSS实现精美的二级导航效果代码
2015/09/17 Javascript
微信小程序 动态传参实例详解
2017/04/27 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
微信小程序 数据缓存实现方法详解
2019/08/26 Javascript
JavaScript运行机制实例分析
2020/04/11 Javascript
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
[54:19]完美世界DOTA2联赛PWL S2 Magma vs PXG 第二场 11.28
2020/12/01 DOTA
Python实现的监测服务器硬盘使用率脚本分享
2014/11/07 Python
python中如何正确使用正则表达式的详细模式(Verbose mode expression)
2017/11/08 Python
基于Pandas读取csv文件Error的总结
2018/06/15 Python
python实现本地图片转存并重命名的示例代码
2018/10/27 Python
python对视频画框标记后保存的方法
2018/12/07 Python
django项目环境搭建及在虚拟机本地创建django项目的教程
2019/08/02 Python
pandas中DataFrame修改index、columns名的方法示例
2019/08/02 Python
tensorflow 大于某个值为1,小于为0的实例
2020/06/30 Python
Python matplotlib图例放在外侧保存时显示不完整问题解决
2020/07/28 Python
CSS3 渐变(Gradients)之CSS3 径向渐变
2016/07/08 HTML / CSS
耐克巴西官方网站:Nike巴西
2016/08/14 全球购物
大学生个人总结的自我评价
2013/10/05 职场文书
大学生个人自荐信样本
2014/03/02 职场文书
食堂采购员岗位职责
2014/03/17 职场文书
建筑工程专业大学生求职信
2014/04/23 职场文书
安全目标管理责任书
2014/07/25 职场文书
单位法定代表人授权委托书
2014/09/20 职场文书
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
2014年企业工会工作总结
2014/11/12 职场文书
创业计划书之冷饮店
2019/09/27 职场文书
导游词之苏州盘门景区
2019/11/12 职场文书
pytorch训练神经网络爆内存的解决方案
2021/05/22 Python