当前位置: 首页 > 后端技术 > Python

Python爬取《赘婿》弹幕

时间:2023-03-26 19:02:43 Python

前言最近工作代码中遇到了一些小问题,导致我的更新速度慢了很多。今天想和大家分享一下我之前遇到的问题,通过一个实用的内容来教大家。希望大家以后遇到类似问题的时候,能够想到我的文章,解决问题。今天要分享的知识是关于xml文件的解析。什么是XMLXML是指ExtensibleMarkupLanguage,是StandardGeneralMarkupLanguage的一个子集,是一种用于标记电子文档使其结构化的标记语言。XML旨在传输和存储数据。XML是一组定义语义的标记规则,这些标记标识文档的许多部分并标识这些部分。他也是一种元标记语言,它定义了一种语法语言,用于定义其他领域相关的、语义的和结构化的标记语言。Python解析XML。有两个主要的XML接口:DOM和SAX。XML方式不同,当然使用的场景也不同。SAX(用于XML的简单API)Python标准库包括一个SAX解析器。SAX使用事件驱动的模型来处理XML文件,在解析XML和调用用户自定义回调函数的过程中一个一个地触发事件。DOM(DocumentObjectModel)将XML数据解析成内存中的一棵树,通过操作树来操作XML。本次分享中使用的XML文件为movies.xml,内容如下:War,ThrillerDVD2003PG10聊美日战争动漫、科幻DVD1989R8科学类fiction动漫,动作DVD4PG10VashtheStampede!喜剧VHSPG2可看无聊对于现在,我们比较常见的解析方式是使用DOM模块进行解析Python解析XML示例fromxml.dom.minidomimportparseimportxml.dom.minidom#使用minidom解析器打开XML文档DOMTree=xml.dom.minidom.parse('movies.xml')#ReturnDocumentobjectcollection=DOMTree.documentElement#获取元素操作对象#print(collection)ifcollection.hasAttribute('shelf'):print('Rootelement:%s'%collection.getAttribute('shelf'))#获取集合中的所有电影movies=collection.getElementsByTagName('movie')#返回所有电影标签并将它们保存在列表中#print(movies)formovieinmovies:print('******movie******')ifmovie.hasAttribute('title'):print('Title:%s'%movie.getAttribute('title'))type=movie.getElementsByTagName('type')[0]print('Type:%s'%type.childNodes[0].data)#获取标签元素的内容format=movie.getElementsByTagName('format')[0]print('format:%s'%format.childNodes[0].data)rating=movie.getElementsByTagName('rating')[0]print('rating:%s'%rating.childNodes[0].data)description=电影.getElementsByTagName('描述')[0]打印('描述on:%s'%description.childNodes[0].data)爱奇艺弹幕最近出新剧了,名字就叫《赘婿》,大家一定看过吧抓屏分享给大家,我在爬取过程中遇到的内容。分析网页一般来说,视频弹幕是不可能出现在网页源码中的,所以初步判断是异步加载弹幕数据。首先打开开发者工具-->点击网络-->点击XHRimage,找到类似上图的URL,我们只需要其中一个:/54/00/7973227714515400。爱奇艺弹幕地址获取如下:https://cmts.iqiyi.com/bullet/parameter1_300_parameter2.z参数1为:/54/00/7973227714515400参数2为:数字1,2,3。。....爱奇艺每5分钟加载一次弹幕,每集约46分钟,所以弹幕链接如下:https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_1。zhttps://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_2.zhttps://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_3.z...https://cmts.iqicom/bullet/54/00/7973227714515400_300_10.z数据解码将以上网址复制到浏览器中,会发现会直接下载一个后缀为.z的压缩包,windows无法直接打开,只能打开先通过Python对压缩包进行解码。这里我先简单介绍一下zlib库,它是用来压缩和解压数据流的。因此,我们可以对下载的数据包进行解压。首先,需要以二进制形式读取数据包,然后解压缩。以我刚刚下载的压缩包为例。具体代码如下:importzlibwithopen('7973227714515400_300_1.z','rb')asf:data=f.read()decode=zlib.decompress(bytearray(data),15+32).decode('utf-8')print(decode)结果,如下图:image不知道大家有没有发现这种数据看起来像XML,那我们不妨多写两行代码把数据保存为一个XML文件。具体代码如下:importzlibwithopen('7973227714515400_300_1.z','rb')asf:data=f.read()decode=zlib.decompress(bytearray(data),15+32).decode('utf-8')withopen('zx-1.xml','w',encoding='utf-8')asf:f.write(decode)得到的XML文件内容如下:见image运行结果后,是不是有点小惊喜呢?按照我上面说的,我们就可以得到我们想要的数据了。提取数据的具体代码如下:fromxml.dom.minidomimportparseimportxml.dom.minidomDOMTree=xml.dom.minidom.parse('zx-1.xml')collection=DOMTree.documentElemententrys=collection.getElementsByTagName('entry')forentryinentries:content=entry.getElementsByTagName('content')[0].childNodes[0].dataprint(content)结果,如下图:image下面分析网页和思路数据获取想必大家都明白。现在我们需要回到刚才的起点。我们需要构建一个弹幕URL,向该URL发送请求,获取其二进制数据,解压并保存为XML文件,最后从文件中提取弹幕数据。.构造URL的具体代码如下:#ConstructURLdefget_urls(self):urls=[]forxinrange(1,11):url=f'https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_{x}.z'urls.append(url)returnurls保存xml文件的具体代码如下:#保存xml文件defget_xml(self):urls=self.get_urls()count=1forurlinurls:content=requests.get(url,headers=self.headers).contentdecode=zlib.decompress(bytearray(content),15+32).decode('utf-8')withopen(f'../data/zx-{count}.xml','a',encoding='utf-8')asf:f.write(decode)count+=1避坑:1.首先我们的内容想要获取的其实是一个压缩包,所以我们的header应该这样写:self.headers={'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/88.0.4324.150Safari/537.36','Accept-Encoding':'gzip,deflate'}避免出现如下错误:image2,保存的xml文件不能中文命名,和ano还有一点就是最好加个-,如下图:zx-0zx-1...zx-9避免了如下错误:image保存完所有的XML文件后,暂时把爬虫代码注释掉,因为接下来我们需要从上面的文件中提取数据。提取数据#提取数据defparse_data(self):danmus=[]forxinrange(1,11):DOMTree=xml.dom.minidom.parse(f'../data/zx-{x}.xml')collection=DOMTree.documentElemententries=collection.getElementsByTagName('entry')对于条目中的条目:danmu=entry.getElementsByTagName('content')[0].childNodes[0].datadanmus.append(danmu)#print(danmus)df=pd.DataFrame({'danmus':danmus})returndf这里我们刚用到,刚学的XML解析方法。所以对于我们来说,提取里面的弹幕基本是没有问题的。保存数据#保存数据defsave_data(self):df=self.parse_data()df.to_csv('../data/danmu.csv',encoding='utf-8-sig',index=False)注释内容词云图的小伙伴们注意了,这只是第一集,还有2000多个弹幕。由此可见,这部剧还是比较受欢迎的。归根结底,没有什么是一蹴而就的,生活如此,学习亦然!所以哪里有三日崩盘、七日崩盘的说法呢?只有坚持,才能成功!