lxml beautiful pyquery三种解析库

这两天看了一下python常用的三种解析库,写篇随笔,整理一下思路。太菜了,若有错误的地方,欢迎大家随时指正。。。。。。。(come on.......)

爬取网页数据一般会经过 获取信息->提取信息->保存信息 这三个步骤。而解析库的使用,则可以帮助我们快速的提取出我们需要的那被部分信息,免去了写复杂的正则表达式的麻烦。在使用解析库的时候,个人理解也会有三个步骤 建立文档树->搜索文档树->获取属性和文本 。

建立文档树:就是把我们获取到的网页源码利用解析库进行解析,只有这样,后面才能使用这个解析库的方法。

搜索文档树:就是在已经建立的文档树里面,利用标签的属性,搜索出我们需要的那部分信息,比如一个包含一部分网页内容的div标签,一个ul标签等。

获取索性和文本:在上一步的基础上,进一步获取到具体某个标签的文本或属性,比如一个a标签的href属性,title属性,或它的文本。

 

先来介绍lxml,这个库用到了 Xpath 语法,不过在Google里可以直接copy某个元素的xpath路径,非常的方便。

首先,定义一个html的字符串,用它来模拟已经获取到的网页源码

html = '''
<div id="container">
    <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
     <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>
'''
View Code

 

1.建立文档树:在获取到网页源码后,只需要使用etree的HTML方法,就可以把复杂的html建立成 一棵文档树了

from lxml import etree
xpath_tree = etree.HTML(html)

 

这里首先导入lxml库的etree模块,然后声明了一段HTML文本,调用HTML类进行初始化,这样就成功构造了一个XPath解析对象。可以使用type查看一下xpath_tree的类型,是这样的 <class 'lxml.etree._Element'>

2.搜索文档树:先看一下xpath几个常用的规则

(1)从整个文档树中搜索标签:一般会用//开头的XPath规则来选取所有符合要求的节点。这里以前面的HTML文本为例。例如搜索 ul 标签

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('ul')  //括号里面也可以是元素的xpath路径,在google里复制过来粘贴就行
3 print(result)
4 print(type(result))
5 print(type(result[0]))

输出结果如下:
[<Element ul at 0x2322b7e8608>, <Element ul at 0x2322b7e8648>]
<class 'list'>
<class 'lxml.etree._Element'>

 上面第二行代码表示从整个文档树中搜索出所有的ul标签,可以看到,返回结果是一个列表,里面的每个元素都是lxml.etree._Element类型,当然,也可以对这个列表进行一个遍历,然后对每个lxml.etree._Element对象进行操作。

 

(2)搜索当前节点的子节点:比如,找到每一个ul标签里面的 li 标签:

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul')
3 for r in result:
4     li_list = r.xpath('./li')
5     print(li_list)

输出结果如下:
[<Element li at 0x23433127748>, <Element li at 0x23433127788>, <Element li at 0x23433127a88>, <Element li at 0x23433127988>, <Element li at 0x23433127ac8>]
[<Element li at 0x23433127cc8>, <Element li at 0x23433127d08>, <Element li at 0x23433127d48>, <Element li at 0x23433127d88>, <Element li at 0x23433127dc8>]

 第四行代码表示,选取当前的这个ul标签,并获取到它里面的所有li标签。

 

(3)根据属性过滤:如果你需要根据标签的属性进行一个过滤,则可以这样来做

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul')
3 for r in result:
4     li_list = r.xpath('./li[@class="item-0"]')
5     print(li_list)

输出结果如下:
[<Element li at 0x15c436695c8>, <Element li at 0x15c436698c8>]
[<Element li at 0x15c43669988>, <Element li at 0x15c436699c8>]

 与之前的代码相比,旨在第四行的后面加了 [@class="item-0"] ,它表示找到当前ul标签下所有class属性值为item-0的li标签,当然,也可以在整个文档树搜索某个标签时,在标签后面加上某个属性,进行过滤,下面例子中有用到

 

(4)获取文本:获取具体某个标签的文本内容

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul[@class="list"]')
3 for r in result:
4     li_list = r.xpath('./li[@class="item-0"]')
5     for li in li_list:
6         print(li.xpath('./text()'))

输出结果如下:
['first item']
[]
['first item']
[]

首先,在第二行的ul标签后面加了属性过滤,但因为两个ul标签的class属性值都是list,所以结果没加之前是一样的。然后又加了一个for循环,用来获取列表里面每一个元素的文本,因为第二个li标签里面没有文本内容,所以是空

 

(5)获取属性:获取具体某个标签的某个属性内容

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul[@class="list"]')
3 for r in result:
4     li_list = r.xpath('./li[@class="item-0"]')
5     for li in li_list:
6         print(li.xpath('./@class'))

输出结果如下:
['item-0']
['item-0']
['item-0']
['item-0']

 把第六行的text()方法换成@符号,并在后面加上想要的属性,就获取到了该属性的属性值。

 

这是xpath这个解析库基本的使用方法,也有一些没说到的地方,大家可以看一下大佬的文章。https://cuiqingcai.com/5545.html

另外两个解析库,放在后面两篇随笔里面

beautifulsoup解析库:https://www.cnblogs.com/liangxiyang/p/11302525.html

pyquery解析库:https://www.cnblogs.com/liangxiyang/p/11303142.html

*************************不积跬步,无以至千里。*************************

posted @ 2019-08-05 11:37  梁十安  阅读(840)  评论(0编辑  收藏  举报