Python中使用Xpath

news/2024/7/19 11:50:18 标签: Python, lxml, xpath, 爬虫

XPath在Python爬虫学习中,起着举足轻重的地位,对比正则表达式 re两者可以完成同样的工作,实现的功能也差不多,但XPath明显比re具有优势,在网页分析上使re退居二线。

XPath介绍:
是什么? 全称为XML Path Language 一种小型的查询语言
说道XPath是门语言,不得不说它所具备的优点:
1) 可在XML中查找信息
2) 支持HTML的查找
3) 通过元素和属性进行导航

python开发使用XPath条件:
由于XPath属于lxml库模块,所以首先要安装库lxml,具体的安装过程可以查看博客,包括easy_install 和 pip 的安装方法。

XPath的简单调用方法:

from lxml import etree

selector=etree.HTML(源码) #将源码转化为能被XPath匹配的格式

selector.xpath(表达式) #返回为一列表

XPath的使用方法:
首先讲一下XPath的基本语法知识:
四种标签的使用方法
1) // 双斜杠 定位根节点,会对全文进行扫描,在文档中选取所有符合条件的内容,以列表的形式返回。
2) / 单斜杠 寻找当前标签路径的下一层路径标签或者对当前路标签内容进行操作
3) /text() 获取当前路径下的文本内容
4) /@xxxx 提取当前路径下标签的属性值
5) | 可选符 使用|可选取若干个路径 如//p | //div 即在当前路径下选取所有符合条件的p标签和div标签。
6) . 点 用来选取当前节点
7) .. 双点 选取当前节点的父节点
另外还有starts-with(@属性名称,属性字符相同部分),string(.)两种重要的特殊方法后面将重点讲。

利用实例讲解XPath的使用:

from lxml import etree  
html="""  
<!DOCTYPE html>  
<html>  
<head lang="en">  
<title>测试</title>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
</head>  
<body>  
<div id="content">  
<ul id="ul">  
<li>NO.1</li>  
<li>NO.2</li>  
<li>NO.3</li>  
</ul>  
<ul id="ul2">  
<li>one</li>  
<li>two</li>  
</ul>  
</div>  
<div id="url">  
<a href="http:www.58.com" title="58">58</a>  
<a href="http:www.csdn.net" title="CSDN">CSDN</a>  
</div>  
</body>  
</html>  

selector=etree.HTML(html)
content=selector.xpath(‘//div[@id=”content”]/ul[@id=”ul”]/li/text()’) #这里使用id属性来定位哪个div和ul被匹配 使用text()获取文本内容
for i in content:
print i

输出为

NO.1
NO.2
NO.3

con=selector.xpath(‘//a/@href’) #这里使用//从全文中定位符合条件的a标签,使用“@标签属性”获取a便签的href属性值
for each in con:
print each

输出结果为:

http:www.58.com
http:www.csdn.net

con=selector.xpath(‘/html/body/div/a/@title’) #使用绝对路径�20

输出结果为:

2
58 CSDN

介绍XPath的特殊用法:
1) starts-with 解决标签属性值以相同字符串开头的情况

举例说明

from lxml import etree
html="""
    <body>
        <div id="aa">aa</div>
        <div id="ab">ab</div>
        <div id="ac">ac</div>
    </body>
    """
selector=etree.HTML(html)
content=selector.xpath('//div[starts-with(@id,"a")]/text()') #这里使用starts-with方法提取div的id标签属性值开头为a的div标签
for each in content:
    print each
#输出结果为:
aa
ab
ac

2) string(.) 标签套标签

html="""
    <div id="a">
    left
        <span id="b">
        right
            <ul>
            up
                <li>down</li>
            </ul>
        east
        </span>
        west
    </div>
"""
#下面是没有用string方法的输出
sel=etree.HTML(html)
con=sel.xpath('//div[@id="a"]/text()')
for i in con:
    print i   #输出内容为left west

data=sel.xpath('//div[@id="a"]')[0]
info=data.xpath('string(.)')
content=info.replace('\n','').replace(' ','')
for i in content:
    print i #输出为 全部内容

XPath提供的几个特殊的方法:
XPath中需要取的标签如果没有属性,可以使用text(),posision()来识别标签。

举两个简单的例子:

from lxml import etree
html="""
    <div>hello
        <p>H</p>
</div>
<div>hehe</div>
"""
sel=etree.HTML(html)
con=sel.xpath('//div[text()="hello"]/p/text()')
print con[0]
#H

这里使用text()的方法来判别是哪个div标签

from lxml import etree
html="""
    <div>hello
        <p>H</p>
        <p>J</p>
        <p>I</p>
</div>
<div>hehe</div>
"""
sel=etree.HTML(html)
con=sel.xpath('//div[text()="hello"]/p[posision()=2]/text()')
print con[0]
#J

另外,在XPath中可以使用多重过滤方法寻找标签,例如ul[3][@id=”a”] 这里使用【3】来寻找第三个ul标签 并且它的id属性值为a

获取XPath的方式有两种:
1) 使用以上等等的方法通过观察找规律的方式来获取XPath
2) 使用Chrome浏览器来获取 在网页中右击->选择审查元素(或者使用F12打开) 就可以在elements中查看网页的html标签了,找到你想要获取XPath的标签,右击->Copy XPath 就已经将XPath路径复制到了剪切板。

Demo

“`
from lxml import html

def parse():
“”” 将html文件中的内容,使用xpath进行提取 “””
# 读取文件中的内容
f = open(‘./static/index.html’, ‘r’, encoding=’utf-8’)
s = f.read()

selector = html.fromstring(s)
# 解析H3标题
h3 = selector.xpath('/html/body/h3/text()')
print(h3[0])


# 解析ul下面的内容
# ul = selector.xpath('/html/body/ul/li')
ul = selector.xpath('//ul/li')
print(len(ul))
for li in ul:
    print(li.xpath('text()')[0])

# 解析ul指定的元素值
ul2 = selector.xpath('/html/body/ul/li[@class="important"]/text()')
print(ul2)

# 解析a标签的内容
a = selector.xpath('//div[@id="container"]/a/text()')
# 标签内的内容
print(a[0])
# href属性
alink = selector.xpath('//div[@id="container"]/a/@href')
print(alink[0])

# 解析P标签
p = selector.xpath('/html/body/p[last()]/text()')
print(len(p))
print(p[0])

test = selector.xpath('/html/body/ul/li[3]/text()')
print(test[0])

f.close()

if name == ‘main‘:
parse()

```

http://www.niftyadmin.cn/n/814108.html

相关文章

tableview随笔

//获得row NSInteger row [[self.treeTableViewindexPathForCell:(UITableViewCell *)[[[notification.userInfoobjectForKey:senderKey] superview] superview]] row]; //获得section NSInteger section [[self.treeTableViewindexPathForCell:(UITableViewCell *)[[[notifi…

JavaScript中的this到底指向谁?

很多初学JavaScript的小伙伴,都找不准函数或者方法中的this到底指向谁,其实并没有那么复杂,只需要记住一个口诀就能正确找到this的指向:不管函数或者方法是如何声明的,要看这个函数或者方法最终是谁调用的,**谁最终调用这个函数或方法,那么这个函数或方法中的this就是谁**. 下面…

【Qt】Qstring

//http://devbean.blog.51cto.com/448512/275360 //http://doc.qt.io/qt-5/qstring.html 今天要说的是QString。之所以把QString单独拿出来&#xff0c;是因为string是很常用的一个数据结构&#xff0c;甚至在很多语言中&#xff0c;比如JavaScript&#xff0c;都是把string作…

iOS事件拦截(实现触摸任意位置隐藏指定view)

项目里有一个需求&#xff0c;类似新浪或者腾讯微博的顶部title栏的类别选择器的消失&#xff08;在选择器展开的时候&#xff0c;触摸屏幕任何地方使其消失&#xff09;。 最开始的想法是当这个选择器&#xff08;selectorView&#xff09;展开的时候&#xff0c;在当前屏幕上…

30道Redis面试题

什么是Redis&#xff1f;简述它的优缺点&#xff1f; A Redis本质上是一个Key-Value类型的内存数据库&#xff0c;很像memcached&#xff0c;整个数据库统统加载在内存当中进行操作&#xff0c;定期通过异步操作把数据库数据flush到硬盘上进行保存。 因为是纯内存操作&#…

显示隐藏模块实现的几种方式

显示隐藏模块实现的几种方式 网页结构&#xff1a; <style> body {width: 400px;margin: 0 auto; } .btn {width:50%;height: 30px; } #box {width: 200px;height&#xff1a;100px;background-color: red;overflow: hidden; } </style><button id"btn-s…

一位转行小白的内心独白

半年多的JavaEE学习生活结束了&#xff0c;也是我进入IT行业的开始。对于一个投身于IT的新人&#xff0c;经验谈不上&#xff0c;一些学习的心得倒是可以拿出来探讨一下&#xff0c;我们该如何面临这个似曾相识的社会&#xff0c;突然一天如此接近。面对“全球经济不景气”带来…

将NavigationBar设置透明

转载自&#xff1a;http://blog.sina.com.cn/s/blog_621403ef0100tuna.html 将NavigationBar设置透明&#xff08;仅将指定视图控制器进行透明处理&#xff09;&#xff0c;步骤如下&#xff1a;1.在视图控制器的头文件中实现UINavigationControllerDelegate&#xff0c;例如&a…