使用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的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
Jul 09 Python
python数据清洗系列之字符串处理详解
Feb 12 Python
Python实现读取字符串按列分配后按行输出示例
Apr 17 Python
python实现对求解最长回文子串的动态规划算法
Jun 02 Python
对python多线程与global变量详解
Nov 09 Python
PyGame贪吃蛇的实现代码示例
Nov 21 Python
解决.ui文件生成的.py文件运行不出现界面的方法
Jun 19 Python
Keras-多输入多输出实例(多任务)
Jun 22 Python
详解python的内存分配机制
May 10 Python
Python基础之进程详解
May 21 Python
Python利用zhdate模块实现农历日期处理
Mar 31 Python
基于PyQt5制作一个群发邮件工具
Apr 08 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
第二节 对象模型 [2]
2006/10/09 PHP
用php来检测proxy
2006/10/09 PHP
探讨file_get_contents与curl效率及稳定性的分析
2013/06/06 PHP
解析PHP留言本模块主要功能的函数说明(代码可实现)
2013/06/25 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
Codeigniter实现智能裁剪图片的方法
2014/06/12 PHP
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
php计算税后工资的方法
2015/07/28 PHP
用 Javascript 验证表单(form)中的单选(radio)值
2009/09/08 Javascript
jQuery each()小议
2010/03/18 Javascript
javascript 获取页面的高度及滚动条的位置的代码
2010/05/06 Javascript
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2012/07/21 Javascript
JQuery拖拽元素改变大小尺寸实现代码
2012/12/10 Javascript
网站如何做到完全不需要jQuery也可以满足简单需求
2013/06/27 Javascript
JavaScript 作用域链解析
2014/11/13 Javascript
javascript中使用正则表达式清理table样式的代码
2020/04/01 Javascript
angularjs select 赋值 ng-options配置方法
2018/02/28 Javascript
JavaScript使用类似break机制中断forEach循环的方法
2018/11/13 Javascript
JavaScript中concat复制数组方法浅析
2019/01/20 Javascript
解决layer 关闭当前弹窗 关闭遮罩层 input值获取不到的问题
2019/09/25 Javascript
python选择排序算法的实现代码
2013/11/21 Python
详解Python中with语句的用法
2015/04/15 Python
Python解析并读取PDF文件内容的方法
2018/05/08 Python
浅谈PyTorch中in-place operation的含义
2020/06/27 Python
python打包生成so文件的实现
2020/10/30 Python
详解Python openpyxl库的基本应用
2021/02/26 Python
HTML5实现的图片无限加载的瀑布流效果另带边框圆角阴影
2014/03/07 HTML / CSS
西班牙著名的珠宝首饰品牌:P D PAOLA
2018/09/15 全球购物
Steiff台湾官网:德国金耳釦泰迪熊
2019/12/26 全球购物
资源环境与城乡规划管理专业自荐书
2014/09/26 职场文书
小学教师暑期培训心得体会
2016/01/09 职场文书
长辈生日祝福语大全(72句)
2019/08/09 职场文书
Python基础之常用库常用方法整理
2021/04/30 Python
《异世界四重奏》剧场版6月10日上映 PV视觉图原创角色发表
2022/03/20 日漫
html5+实现plus.io进行拍照和图片等获取
2022/06/01 HTML / CSS