python中的切片冒号的用法(大杀器之xpath与lxml之数据处理)
python中的切片冒号的用法(大杀器之xpath与lxml之数据处理)Lxml也是唯一支持解析XMl的库哦。Lxml 是基于libxml2库的Python封装。lxml使用C语言编写,解析速度比Beautiful Soup更快 最新版本的lxml支持CPython2.6至3.6的版本。数据下载之后是很原始的数据,此时我们接下来当然是从数据中筛选出对我们有用的数据了。此时常用的方式有使用正则、css、或者xpath等锁定目标数据并抽取出来。二、lxml与XPath
一、前言:
-
现在到处都在说大数据,机器学习,深度学习。
-
然后数据是哪里来的呢?要么你是bat这类公司,手握大量数据,一般情况下,我们都是需要通过一些必要的手段来获取数据。
-
而说到获取数据,就离不开我们的网络爬虫,也有叫网络蜘蛛之类的等等,但本质就是一个不断从从Internt上下载数据的程序。
-
数据下载之后是很原始的数据,此时我们接下来当然是从数据中筛选出对我们有用的数据了。
-
此时常用的方式有使用正则、css、或者xpath等锁定目标数据并抽取出来。
二、lxml与XPath
-
Lxml 是基于libxml2库的Python封装。lxml使用C语言编写,解析速度比Beautiful Soup更快 最新版本的lxml支持CPython2.6至3.6的版本。
-
Lxml也是唯一支持解析XMl的库哦。
-
XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言,也就是说可以用来表示xml文档中的某个节点部分。
-
XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。而我们抓取下来的数据如果是HTML,此时一般我们可以先将html通过某鞋工具库转换为xml结构的数据。
-
转换好之后当然就可以愉快的用我们的xpath语法进行数据抽取了。
-
其实我是很喜欢xpath的,因为其编写的代码简洁,功能强大。
三、lxml学习教程
-
本次学习我们将采用lxml库来进行操作。
-
lxml库作为python第三方库中最受欢迎的库,其底层采用C语言进行编写从而给使用者带来极好的解析速度体验。
lxml的安装
-
python3安装:pip3 install lxml
lxml.etree处理xml
-
1、首先我们先导入etree
-
from lxml import etree
element 类:
-
Element是ElementTree API的主要容器对象。大多数XML树功能都是通过这个类访问的。Element可以通过Element工厂轻松创建:
-
root = etree.Element(‘root’);
-
我们你可以通过访问Element的tag属性获取元素的标签名称
-
root.tag -> root
-
Element以XML树结构进行组织数据。要创建子元素并将其添加到父元素中,可以使用append()方法:
-
root.append( etree.Element(“child1”) );
-
我们还可以用一个更短的和更有效的方法来做到这一点:SubElement工厂。它接受与元素工厂相同的参数,但要求父节点作为第一个参数:
-
child2 = etree.SubElement(root “child2”);
-
child3 = etree.SubElement(root “child3”);
Elements列表
-
我们创建的root等元素其实是一个列表累的哦
-
我们可以这样访问创建的child2的元素名称
-
root[0].tag
-
获取root的子元素长度
-
len(root)
-
判断子元素的父元素
-
root is root[0].getparent();
-
判断一个元素是否在其兄弟元素的前面
-
我们这里的child1和child2即为兄弟元素
-
判断root[0]是否是root[1]的前一个元素
-
root[0] is root[1].getprevious()
-
判断root[1]是否是root[0]的后一个元素
-
root[1] is root[0].getnext()
元素携带的属性
-
元素所携带的属性将以字典的形式进行存储,以下我们为root添加一个class属性
-
root = etree.Element(‘root’ attrib={‘class’:‘hello’});
-
打印结果为:
-
<root class="hello"/>
-
我们也可以在创建了元素之后添加属性:
-
root.set(‘id’ world);
-
打印结果为:
-
<root class="hello" id="world"/>
-
设置属性之后,我们想要读取属性也是非常容易的。
-
root.get(‘class’);
-
输出为:hello
-
我们可以通过keys()方法获取元素的所有属性集合,其以列表的形式返回给我们
-
root.keys();
-
输出为:[‘class’ ‘id’]
-
我们可以通过values()方法获取元素的所有属性对应的值的集合,其以列表的形式返回给我们
-
root.values();
-
输出为:[‘hello’ ‘world’]
-
items()则以元组列表的形式返回所有的属性集合:
-
root.items();
-
输出结果为:[(‘class’ ‘hello’) (‘id’ ‘world’)]
-
元素的attrib属性负责存储我们的属性集合,我们也可以直接取出来进行设置
-
at = root.attrib;
-
at[‘class’]=‘hello’;
-
root.set(‘class’ ‘hello’)两者是等价的
Text
-
元素的text属性存储了元素的内容。
-
如我们需要在创建
<title>hello</title>
-
root = etree.Element(“root”);
-
root.text=‘hello’;
-
print(etree.tostring(root pretty_print=True))
-
输出为:
<title>hello</title>
-
以上也部分证明了root其实是一个列表哦。
xpath抽取内容
-
我们可以使用元素自身提供的xpath去获取title内部的内容,结果以列表的形式返回
-
root.xpath(‘//title/text()’);
-
输出为:[‘hello’]
-
我们还可以判断获取的内容是不是text
-
text = root.xpath(‘//text()’);
-
print(text[0].is_text)
-
输出内容为:True
元素的迭代
-
我们有时候希望遍历整个文档的内容,for in语句当然是我们最常用的了。
-
lxml的元素本身也提供了迭代的能力
-
root = etree.Element(“root”)
-
etree.SubElement(root “child”).text = “Child 1”
-
etree.SubElement(root “child”).text = “Child 2”
-
etree.SubElement(root “another”).text = “Child 3”
-
for element in root.iter():print(“%s - %s” % (element.tag element.text))
-
结果输出为
-
我们解析的文本有可能是一个本地文件,也有可能是网上请求的一个string,一般我们可以使用fromstring()和XML()两个方法来加载需要解析的数据。
-
当然,一般如果你是用在爬虫项目中,可能更多的就是使用HTML()方法了
-
示例代码:
-
结果输出为:
-
结果解析,我们可以看到,HTML()返回的是一个html类型的Element元素。其内部帮我们增加了html必备的html元素和body元素。
xpath进阶学习
-
在进一步学习xpath之前,我贴两张网上收集的非常好的使用学习资料
-
OK 我们根据上面的示例代码,通过从中获取div、ul、li等标签来学习xpath的使用技巧。
-
获取div标签
-
div_tag = root.xpath(‘//div’)
-
print(div_tag)
-
打印输出为:[<Element div at 0x10b681f88>]
-
获取ul标签
-
ul_tag = root.xpath(‘//div/ul’)
-
print(ul_tag)
-
打印输出为:[<Element ul at 0x10bdfde48>]
-
获取li标签:
-
li_tag = root.xpath(‘//div/ul/li’)
-
print(li_tag)
-
[<Element li at 0x10bdfdd48> <Element li at 0x10bdfdec8> <Element li at 0x10bdfdf08> <Element li at 0x10bdfdf48>]
-
从上面三个示例可以看到,其返回结果为我们xpath表达式定位的标签列表。
-
返回的数据均为Element元素,这样保证了我们的抽取结果可以继续使用Element类的能力,你可以通过Elementapi继续抽取数据,也可以继续通过xpath继续抽取数据。
-
我们也可以直接获取带某个属性的元素集合:
-
class_tag = root.xpath(‘//@class’)
-
print(class_tag)
-
结果输出为:[‘item-0’ ‘item-1’ ‘item-2’ ‘item-3’]
-
如此我们便获取了带class属性的值集合。
-
我们来获取class="item-0"下面的a标签
-
li1 = root.xpath(‘//div/ul/li[@class=“item-0”]/a’);
-
print(li1)
-
[<Element a at 0x10c4a1048>]
-
当然,我们也可以换个方式,我们获取href="link1.html"的a标签
-
li1 = root.xpath(‘//li/a[@href=“link1.html”]’);
-
print(li1)
-
[<Element a at 0x10f5aa048>]
-
获取最后一个li标签里面的a标签的href属性的值
-
href_value = root.xpath(‘//li[last()]/a/@href’);
-
print(href_value)
-
[‘link4.html’]
-
通过上面实例的练习,相信大家对 XPath 的基本用法有了基本的了解。
-
大家可以根据实际情况继续深入学习。
-
XPath 是一个非常好用的解析方法,同时也作为爬虫学习的基础,小编很喜欢。在后面的爬虫抽取数据部分会经常用到。
@著作权归作者所有,转载请联系作者 用心写好每一篇文章