在进行网页抓取的时候,分析定位html节点是获取抓取信息的关键,目前我用的是lxml模块(用来分析XML文档结构的,当然也能分析html结构), 利用其lxmlhtml的xpath对html进行分析,获取抓取信息。
首先,我们需要安装一个支持xpath的python库。目前在libxml2的网站上被推荐的python binding是lxml,也有beautifulsoup,不嫌麻烦的话还可以自己用正则表达式去构建,本文以lxml为例讲解。
假设有如下的HTML文档:
1 <html>
2 <body>
3 <form>
4 <div id='leftmenu'>
5 <h3>text</h3>
6 <ul id=’china’><!-- first location -->
7 <li></li>
8 <li></li>
9
10 </ul>
11 <ul id=’england’><!-- second location-->
12 <li></li>
13 <li></li>
14
15 </ul>
16 </div>
17 </form>
18 </body>
19 </html>
直接使用lxml处理:
1 import codecs
2 from lxml import etree
3 f=codecsopen("ceshihtml","r","utf-8")
4 content=fread()
5 fclose()
6 tree=etreeHTML(content)
etree提供了HTML这个解析函数,现在我们可以直接对HTML使用xpath了,是不是有点小激动,现在就尝试下吧。
在使用xpath之前我们先来看看作为对照的jQuery和RE。
在jQuery里要处理这种东西就很简单,特别是假如那个ul节点有id的话(比如是<ul id=’china’>):
$("#china")each(function(){});
具体到此处是:
$("#leftmenu")children("h3:contains('text')")next("ul")each(function(){});
找到id为leftmenu的节点,在其下找到一个内容包含为”text”的h3节点,再取其接下来的一个ul节点。
在python里要是用RE来处理就略麻烦一些:
block_pattern=recompile(u"<h3>档案</h3>()<h3>", reI | reS)
m=block_patternfindall(content)
item_pattern=recompile(u"<li>()</li>", reI | reS)
items=item_patternfindall(m[0])
for i in items:
print i
那么用xpath要怎么做呢?其实跟jQuery是差不多的:
nodes=treexpath("/descendant::ul[@id='china']")
当然,现在没有id的话也就只能用类似于jQuery的方法了。完整的xpath应该是这样写的(注意,原文件中的TAG有大小写的情况,但是在XPATH里只能用小写):
nodes=treexpath(u"/html/body/form/div[@id='leftmenu']/h3[text()='text']/following-sibling::ul[1]")
更简单的方法就是像jQuery那样直接根据id定位:
nodes=treexpath(u"//div[@id='leftmenu']/h3[text()='text']/following-sibling::ul[1]")
这两种方法返回的结果中,nodes[0]就是那个“text”的h3节点后面紧跟的第一个ul节点,这样就可以列出后面所有的ul节点内容了。
如果ul节点下面还有其他的节点,我们要找到更深节点的内容,如下的循环就是把这些节点的文本内容列出:
nodes=nodes[0]xpath("li/a")
for n in nodes:
print ntext
对比三种方法应该可以看出xpath和jQuery对于页面的解析都是基于XML的语义进行,而RE则纯粹是基于plain text。RE对付简单的页面是没有问题,如果页面结构复杂度较高的时候(比如一堆的DIV来回嵌套之类),设计一个恰当的RE pattern可能会远比写一个xpath要复杂。特别是目前主流的基于CSS的页面设计方式,其中大部分关键节点都会有id――对于使用jQuery的页面来说则更是如此,这时xpath相比RE就有了决定性的优势。
附录:基本XPATH语法介绍,详细请参考XPath的官方文档
XPATH基本上是用一种类似目录树的方法来描述在XML文档中的路径。比如用“/”来作为上下层级间的分隔。第一个“/”表示文档的根节点(注意,不是指文档最外层的tag节点,而是指文档本身)。比如对于一个HTML文件来说,最外层的节点应该是”/html”。
同样的,“”和“”分别被用来表示父节点和本节点。
XPATH返回的不一定就是唯一的节点,而是符合条件的所有节点。比如在HTML文档里使用“/html/head/scrpt”就会把head里的所有script节点都取出来。
为了缩小定位范围,往往还需要增加过滤条件。过滤的方法就是用“[”“]”把过滤条件加上。比如在HTML文档里使用“/html/body/div[@id='main']”,即可取出body里id为main的div节点。
其中@id表示属性id,类似的还可以使用如@name, @value, @href, @src, @class…
而 函数text()的意思则是取得节点包含的文本。比如:<div>hello<p>world</p>< /div>中,用”div[text()='hello']“即可取得这个div,而world则是p的text()。
函数position()的意思是取得节点的位置。比如“li[position()=2]”表示取得第二个li节点,它也可以被省略为“li[2]”。
不过要注意的是数字定位和过滤 条件的顺序。比如“ul/li[5][@name='hello']”表示取ul下第五项li,并且其name必须是hello,否则返回空。而如果用 “ul/li[@name='hello'][5]”的意思就不同,它表示寻找ul下第五个name为”hello“的li节点。
此外,“”可以代替所有的节点名,比如用”/html/body//span”可以取出body下第二级的所有span,而不管它上一级是div还是p或是其它什么东东。
而 “descendant::”前缀可以指代任意多层的中间节点,它也可以被省略成一个“/”。比如在整个HTML文档中查找id为“leftmenu”的 div,可以用“/descendant::div[@id='leftmenu']”,也可以简单地使用“ //div[@id='leftmenu']”。
至于“following-sibling::”前缀就如其名所说,表示同一层的下一个节点。”following-sibling::”就是任意下一个节点,而“following-sibling::ul”就是下一个ul节点。
本文主要围绕以xpath和lxml库进行展开:
一、xpath 概念、xpath节点、xpath语法、xpath轴、xpath运算符
二、lxml的安装、lxml的使用、lxml案例
一、xpath
1xpath概念
XPath 是一门在 XML 文档中查找信息的语言。XPath 使用路径表达式在 XML 文档中进行导航 。XPath 包含一个标准函数库 。XPath 是 XSLT 中的主要元素 。XPath 是一个 W3C 标准 。
2xpath节点
xpath有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。
节点关系:父、子、兄弟、先辈、后辈。
3xpath语法
xpath语法在W3c网站上有详细的介绍,这里截取部分知识,供大家学习。
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。下面列出了最有用的路径表达式:
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
XPath 通配符可用来选取未知的 XML 元素。
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
通过在路径表达式中使用"|"运算符,您可以选取若干个路径。
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
4xpath 轴
轴可定义相对于当前节点的节点集。
5xpath运算符
下面列出了可用在 XPath 表达式中的运算符:
好了,xpath的内容就这么多了。接下来我们要介绍一个神器lxml,他的速度很快,曾经一直是我使用beautifulsoup时最钟爱的解析器,没有之一,因为他的速度的确比其他的htmlparser 和html5lib快了许多。
二、lxml
1lxml安装
lxml 是一个xpath格式解析模块,安装很方便,直接pip install lxml 或者easy_install lxml即可。
2lxml 使用
lxml提供了两种解析网页的方式,一种是你解析自己写的离线网页时,另一种 则是解析线上网页。
导入包:
1解析离线网页:
2解析在线网页:
那么我们怎么获取这些标签和标签对应的属性值了,很简单,首先获取标签只需你这样做:
然后我们可以,比方说,你要获取a标签内的文本和它的属性href所对应的值,有两种方法,
1表达式内获取
2表达式外获取
这样就完成了获取,怎么样,是不是很简单了,哈哈哈。
下面再来lxml的解析规则:
3lxml案例
为了偷懒,我决定还是采用urllib那篇文章的代码,哈哈哈,机智如我。
不需要。
XPath即为XML路径语言(XMLPathLanguage),它是一种用来确定XML文档中某部分位置的语言。
xpath在获取一些属性值或者文本信息的时候,需要对引号进行处理。如果匹配的内容都是一类还好说,如果是单双引号混着的就比较难搞了。需要使用xpath的concat函数,类似于sql中的。
1、在浏览器中打开网页。然后//div,就可以找到页面中的所有div了,因为//表示的是任意目录下查找。如图,页面有两个div,所以可以找到两个。
2、要查找类为a的div,可以在div后面用[@class="类名"]来指定,这样没有类名a的div就会被过滤掉,当然,还可以用id,把class改为[@id="id名"]即可。
3、用//,这样div下面的非a标签就会被跳过,直接去找a标签。
4、如果要获取a标签的href,那么可以获取到a标签后用/@href即可获得。
5、如果是获取文本的话,可以用text()这个方法,就会得到a标签里面的内容。
6、斜杠/表示的是获取子元素,比如div下面有两个子元素p,那么//div[2]/p获取的就是第二个div的子元素p。
1 爬取网站 笔趣阁小说
2 网站地址 >
1 XPath是什么
XPath是一门在XML文档中查找信息的语言。XPath可用来在XML文档中对元素和属性进行遍历。
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。
XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初XPath的提出的初衷是将其作为一个通用的、介于XPointer与XSL间的语法模型。但是XPath很快的被开发者采用来当作小型查询语言。
2 Xml示例 可扩展标记语言,标准通用标记语言的子集,简称XML。是一种用于标记电子文件使其具有结构性的标记语言。
在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。早在1998年,W3C就发布了XML10规范,使用它来简化Internet的文档信息传输。
示例:
<?xml version="10" encoding ="ISO-8859-1">
<book>
<title lang="en">Harry Potter</title>
<author>J K Rowling</author>
<year>2005</year>
<price>2999</price>
</book>
XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
上面的XML文档中的节点例子:
路径表达式语法:
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式:
以下面这个xml为例子
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
XPath 通配符可用来选取未知的 XML 元素。
例子:
选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
轴可定义相对于当前节点的节点集。
步的语法:
轴名称::节点测试[谓语]
例子:
获取以xxx开头的元素
例子:xpath(‘//div[stars-with(@class,”test”)]’)
获取包含xxx的元素
例子:xpath(‘//div[contains(@id,”test”)]’)
与的关系
例子:xpath(‘//div[contains(@id,”test”) and contains(@id,”title”)]’)
例子1:xpath(‘//div[contains(text(),”test”)]’)
例子2:xpath(‘//div[@id=”“test]/text()’)
运行结果:
常用表达式实例:
也可以学习下其他作者的文章: >
以上就是关于如何在python中使用xpath全部的内容,包括:如何在python中使用xpath、Python解析库lxml与xpath用法总结、页面元素的值,没有双引号,xpath根据元素文本定位时要加双引号吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)