前言
在近期的工作代码中我遇到了一些小问题,导致了我的更新慢了不少。今天我就想把我在之前遇到的问题分享给大家,并通过一篇实战内容来教会大家,希望各位小伙伴以后遇到类似问题的时候,可以想起我的文章,并解决问题。
今天我要分享的知识是关于xml文件的解析。
什么是XML
XML指可拓展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。XML被设计用来传输和存储数据。XML是一套定义语义的标记规则,这些标记将文档的许多部件并对这些部件加以标识。他也是元标记语言,即定义了用于定义其他领域有关的、语义的、结构化的标记语言的句法语言
Python对XML的解析
常见的XML接口主要有两种DOM和SAX,这两种接口处理XML的方式不同,当然使用的场景也不相同。
- SAX(simple API for XML)
- DOM(Document Object Model)
本次分享中使用的XML文件为movies.xml,内容如下:
War, Thriller
DVD
2003
PG
10
Talk about a US-Japan war
Anime, Science Fiction
DVD
1989
R
8
A schientific fiction
Anime, Action
DVD
4
PG
10
Vash the Stampede!
Comedy
VHS
PG
2
Viewable boredom
就目前来说,我们比较常用的解析方式是使用DOM模块进行解析。
Python解析XML示例
from xml.dom.minidom import parse
import xml.dom.minidom# 使用minidom解析器打开XML文档
DOMTree = xml.dom.minidom.parse('movies.xml')# 返回Document对象
collection = DOMTree.documentElement# 获取元素操作对象
# print(collection)
if collection.hasAttribute('shelf'):
print('Root element : %s' % collection.getAttribute('shelf'))# 在集合中获取所有的电影
movies = collection.getElementsByTagName('movie')# 返回所有的movie标签,并保存在列表中
# print(movies)
for movie in movies:
print('*******movie******')
if movie.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 = movie.getElementsByTagName('description')[0]
print('description: %s' % description.childNodes[0].data)
爱奇艺弹幕 最近出了一篇新剧,叫做《赘婿》,想必大家都看到了吧。今天我们的实战内容就是把观众发送的弹幕抓取下来,并将我在爬取过程中遇到的内容分享给大家。
分析网页 一般来说,视屏的弹幕是不可能出现在网页源码中的,那么初步判断是通过异步加载弹幕数据。
首先打开开发者工具-->点击network-->点击XHR
image
找到类似上图所示的URL,我们只需要其中的:/54/00/7973227714515400。
爱奇艺的弹幕地址获取如下:
https://cmts.iqiyi.com/bullet/参数1_300_参数2.z
参数1是:/54/00/7973227714515400
参数2是:数字1、2、3......
爱奇艺每5分钟就会加载一次弹幕,每一集下来大概是46分钟,因此弹幕的链接如下:
https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_1.z
https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_2.z
https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_3.z
.
.
.
https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_10.z
数据解码 当你把上面的URL复制到浏览器中,你会发现直接下载一个以.z为后缀的压缩包,windows不能直接打开,只能先通过Python对压缩包进行解码。
在这里我先对zlib这个库做简单的解释,zlib用于压缩和解压缩数据流。
因此,我们可以对下载下来的数据包进行解压缩。
首先,需要以二进制的方式读取数据包,再进行解压缩。
就拿我刚刚下载下来的压缩包为例子吧。
具体代码如下所示:
import zlibwith open('7973227714515400_300_1.z', 'rb') as f:
data = https://www.it610.com/article/f.read()decode = zlib.decompress(bytearray(data), 15 + 32).decode('utf-8')
print(decode)
运行结果,如下所示:
文章图片
image
不知道你有没有发现这类数据很像是XML,那我们就不妨写多两行代码,将数据保存为XML文件。
具体代码,如下所示:
import zlibwith open('7973227714515400_300_1.z', 'rb') as f:
data = https://www.it610.com/article/f.read()decode = zlib.decompress(bytearray(data), 15 + 32).decode('utf-8')
with open('zx-1.xml', 'w', encoding='utf-8') as f:
f.write(decode)
得到的XML文件内容,如下所示:
文章图片
image
看到运行运行结果之后是不是有点小惊喜呀,根据我上面所讲的内容就可以获取到我们想要的数据了。
提取数据 具体代码,如下所示:
from xml.dom.minidom import parse
import xml.dom.minidomDOMTree = xml.dom.minidom.parse('zx-1.xml')
collection = DOMTree.documentElement
entrys = collection.getElementsByTagName('entry')
for entry in entrys:
content = entry.getElementsByTagName('content')[0].childNodes[0].data
print(content)
运行结果,如下所示:
【Python爬取《赘婿》弹幕】
文章图片
image
现在对网页的分析和数据的获取思路想必大家都明白了。
那现在我们又需要回到刚刚的起点了,需要构造弹幕URL,并向该URL发送请求,获取它的二进制数据,再进行解压缩并保存为XML文件,最后从该文件中提取弹幕数据。
构造URL 具体代码,如下所示:
# 构造URL
def get_urls(self):
urls = []
for x in range(1, 11):
url = f'https://cmts.iqiyi.com/bullet/54/00/7973227714515400_300_{x}.z'
urls.append(url)
return urls
保存XML文件 具体代码,如下所示:
# 保存xml文件
def get_xml(self):
urls = self.get_urls()
count = 1
for url in urls:
content = requests.get(url, headers=self.headers).content
decode = zlib.decompress(bytearray(content), 15 + 32).decode('utf-8')
with open(f'../data/zx-{count}.xml', 'a', encoding='utf-8') as f:
f.write(decode)
count += 1
避坑:
1、首先我们要获取的内容其实是一个压缩包,因此我们的headers应该这样写:
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0;
Win64;
x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36',
'Accept-Encoding': 'gzip, deflate'
}
避免出现如下错误:
文章图片
image
2、保存的xml文件不能以中文命名,还有一点就是最好添加一个 - ,如下所示:
zx-0
zx-1
.
.
.
zx-9
避免出现如下错误:
文章图片
image
将XML文件都保存下来之后,暂时注释掉爬虫代码,因为,接下来我们需要对上面的文件进行数据提取了。
提取数据
# 提取数据
def parse_data(self):
danmus = []for x in range(1, 11):
DOMTree = xml.dom.minidom.parse(f'../data/zx-{x}.xml')
collection = DOMTree.documentElement
entrys = collection.getElementsByTagName('entry')
for entry in entrys:
danmu = entry.getElementsByTagName('content')[0].childNodes[0].data
danmus.append(danmu)
# print(danmus)
df = pd.DataFrame({
'弹幕': danmus
})
return df
在这里我们刚好使用到了,刚刚学习的XML的解析方式。所以对于我们来说,提取里面的弹幕对我们来说基本上,没有什么问题。
保存数据
# 保存数据
def save_data(self):
df = self.parse_data()
df.to_csv('../data/danmu.csv', encoding='utf-8-sig', index=False)
评论内容词云
文章图片
image
小伙伴们请注意,这个只是第一集,就有两千多条弹幕,由此可以看出,这部剧还是比较火爆的。
最后 没有什么事情是可以一蹴而就的,生活如此,学习亦是如此!
因此,哪里会有什么三天速成,七天速成的说法呢?
唯有坚持,方能成功!
推荐阅读
- python爬pixiv排行榜
- python爬虫|看一小伙如何使用 python爬虫来算命()
- 会计转行能做什么(看完这个故事,让你更清醒)
- Scrapy爬取顶点小说网
- 爬虫系列(数据标准化)
- #Python爬虫#Item Pipeline介绍(附爬取网站获取图片到本地代码)
- Scrapy爬取小说简单逻辑
- Python爬虫,私活接单记录,假日到手5500美滋滋
- 新selenium模拟登录知乎
- 渣本零基础努力自学python,半年成功上岸,良心分享学习心得和踩坑经历