lxml是Python基于xpath做数据解析的工具
from lxml import etree
树: 整个html内容或者整个xml内容
节点:树结构中的每个标签(元素)就是一个节点
根节点:树结构中的第一个节点就是根节点(网页对应树的根节点是html标签)
节点内容:双标签的标签内容
节点属性:标签的标签属性
xml和json都是通用的数据格式,可以用于不同编程语言的程序之间进行数据交流。
json更小更快;xml更安全
用json和xml两种数据格式来传输一个班级的信息:
1)json
{
“name”: “goodstudy”,
“teacher”: {
“name”: “niuzi”,
“tel”: “1100”,
“age”: 18
},
“students”:[
{“name”: “小明”, “age”: 18, “tel”: “120”, “gender”: “男”},
{“name”: “张三”, “age”: 22, “tel”: “119”, “gender”: “女”},
{“name”: “老王”, “age”: 30, “tel”: “140”, “gender”: “男”}
]
}
2)xml
niuzi
1100
18
在说明这个语法前
现在当前目录建一个xml文件
data.xml文件内容如下
<supermarket>
<name>永辉超市name>
<staffs>
<staff>
<name class="c1">张三name>
<position>收营员position>
<salary>3500salary>
staff>
<staff>
<name>小明name>
<position class="c1">收营员position>
<salary>3800salary>
staff>
<staff>
<name class="c1">小花name>
<position>导购position>
<salary>4500salary>
staff>
<staff>
<name>李华name>
<position>导购position>
<salary>5500salary>
staff>
staffs>
<goodsList>
<goods>
<name class="c1">面包name>
<price>5.5price>
<count>12count>
goods>
<goods tag="hot">
<name>泡面name>
<price class="c1">3.5price>
<count>59count>
goods>
<goods tag="discount" discount="0.8">
<name>火腿肠name>
<price>1.5price>
<count>30count>
goods>
<goods tag="hot">
<name>矿泉水name>
<price>2price>
<count>210count>
goods>
goodsList>
supermarket>
节奏开始,导入模块
from lxml import etree
etree.XML(xml数据)
etree.HTML(html数据)
root = etree.XML(open('data.xml', encoding='utf-8').read())
节点对象.xpath(路径) - 获取指定路径对应的所有的标签
xpath语法(路径的写法):
1)绝对路径:不管xpath点前面是哪个标签,绝对路径都是以’/‘开头,从根节点开始往后写
2)相对路径:在写路径的时候用’.‘表示当前节点,用’…‘表示当前节点的上层节点。谁去点的xpath当前节点就是谁
3)全路径:在写路径的时候用’//'开头,获取标签的时候是在整个树中获取所有满足路径结构的标签
staff_names = root.xpath('/supermarket/staffs/staff/name')
print(staff_names)
在路径的最后加'/text()'可以获取标签内容
result = root.xpath('/supermarket/staffs/staff/name/text()')
print(result) # ['张三', '小明', '小花']
注意:不断xpath前面是谁去点的,写绝对路径的时候都必须从根节点开始写
goodsList = root.xpath('/supermarket/goodsList')[0]
result = goodsList.xpath('/supermarket/goodsList/goods/price/text()')
print(result)
result = root.xpath('./staffs/staff/name/text()')
print(result)
goodsList = root.xpath('/supermarket/goodsList')[0]
result = goodsList.xpath('./goods/price/text()')
print(result)
相对路径中’./‘开头的时候,’./'可以不写
result = goodsList.xpath('goods/price/text()')
print(result)
result = root.xpath('//name/text()')
print(result)
result = root.xpath('//goods/name/text()')
print(result)
[N] - 第N个节点
[last()] - 最后一个节点
[last()-N] - [last()-1]: 倒数第2个
[position()>N]、[position()<N]、[position()>=N]、[position()<=N]
"""
result = root.xpath('//staffs/staff[2]/name/text()')
print(result)
result = root.xpath('//staffs/staff[last()]/name/text()')
print(result)
result = root.xpath('//staffs/staff[last()-1]/name/text()')
print(result)
result = root.xpath('//staffs/staff[position()<=2]/name/text()')
print(result)
[@属性名=值] - 获取指定属性为指定值的标签
[@属性名] - 获取拥有指定属性的标签
result = root.xpath('//goodsList/goods[@tag]/name/text()')
print(result)
result = root.xpath('//goods[@tag="hot"]/name/text()')
print(result)
[子标签名=值] - 获取指定子标签的标签内容为指定值的标签
[子标签名>值] - 获取指定子标签的标签内容大于指定值的标签
result = root.xpath('//goods[price=3.5]/name/text()')
print(result)
result = root.xpath('//goods[count>=50]/name/text()')
print(result)
获取标签内容: 获取标签的路径/text() - 获取路径选中的所有的标签的标签内容
获取标签内容: 获取标签的路径/@属性名 - 获取路径选中的所有的标签的指定属性的值
result = root.xpath('//goods[2]/@tag')
print(result)
goods_names = root.xpath('//goods/name')
for x in goods_names:
print(x.xpath('./text()')[0])
result = root.xpath('//goods[1]/*/text()')
print(result)
result = root.xpath('//*[@class="c1"]/text()')
print(result)
result = root.xpath('//goodsList/goods[3]/@*')
print(result)
result = root.xpath('//goods/name/text()|//staff/name/text()')
print(result)