Python爬虫从入门到进阶(4)之xpath的使用

官网地址:https://lxml.de/xpathxslt.html

导入:

 from lxml import etree

lxml.tree 支持 ElementTree 和 Element 上的 find,findall,findtext方法的简单路径语法,作为特定的 lxml 扩展,这些类提供了 xpath()方法,该方法支持完整xpath语法中的表达式,以及定制的扩展函数。

xpath()方法

对于ElementTree,xpath 方法对文档(绝对路径)或者根节点执行全局(相对路径) xpath查询

def demo_1():
    f = StringIO(‘<foo><bar></bar></foo>‘)
    tree = etree.parse(f)
    r = tree.xpath(‘/foo/bar‘)
    print(len(r))
    print(r[0].tag)

    r_2 = tree.xpath(‘bar‘)
    print(r_2[0].tag)

在 Element 上使用 xpath() 时,xpath()表达式根据元素(相对路径)或根树(绝对路径)查询:

def demo_2():
    f = StringIO(‘<foo><bar></bar></foo>‘)
    tree = etree.parse(f)

    root = tree.getroot()
    r = root.xpath(‘bar‘)
    print(r[0].tag)

    bar = root[0]
    r = bar.xpath(‘/foo/bar‘)
    print(r[0].tag)

xpath()方法支持xpath变量:

def demo_3():
    f = StringIO(‘<foo><bar></bar></foo>‘)
    tree = etree.parse(f)
    root = tree.getroot()

    expr = "//*[local-name() = $name]"
    print(root.xpath(expr, name=‘foo‘)[0].tag)
    print(root.xpath(expr, name="bar")[0].tag)
    print(root.xpath("$text", text="Hello World!"))
    

命名空间和前缀

如果XPath表达式使用名称空间前缀,则必须在前缀映射中定义它们。为此,将一个字典传递给namespace关键字参数,该参数将XPath表达式中使用的名称空间前缀映射到名称空间uri

def demo_4():
    f = StringIO(‘‘‘    <a:foo xmlns:a="http://codespeak.net/ns/test1"
           xmlns:b="http://codespeak.net/ns/test2">
        <b:bar>Text</b:bar>
    </a:foo>
    ‘‘‘)

    doc = etree.parse(f)
    r = doc.xpath(‘/x:foo/b:bar‘,
                  namespaces={‘x‘: ‘http://codespeak.net/ns/test1‘,
                              ‘b‘: ‘http://codespeak.net/ns/test2‘})
    print(len(r))
    print(r[0].tag)
    print(r[0].text)

在这里选择的前缀并没有连接到XML文档中使用的前缀,文档可以定义任何前缀,包括空前缀,也不会破坏上面的代码

注意 XPath 没有默认的命名空间,因此,XPath 中没有定义空前缀,不能在命名空间前缀映射中使用

XPath返回值

XPath返回值的类型取决于使用的Xpath 表达式:

  (1) True 或者 False

  (2) float

  (3) “智能的”string

    XPath字符串的结果是“智能的”,因为它们提供了一个getparent()方法,该方法知道它们的起源:

      (i)对于属性值,result.getparent()返回携带它们的元素。例如//foo/@attribute,它的父元素是一个foo元素。

      (ii)对于text()函数(如//text()),它返回包含返回的文本或尾部的元素。

    以使用布尔属性is_text、is_tail和is_attribute来区分不同的文本源。

    注意,getparent()不一定总是返回一个元素。例如,XPath函数string()和concat()将构造没有原点的字符串。对于它们,getparent()将不返回任何值。

    有些情况下 smart string 并不受欢迎。例如:它意味着树将字符串保持活动状态,如果字符串值是树中唯一真正需要的东西,那么它可能会对内存产生相当大的影响。对于这些情况,可以使用关键字 smart_strings禁用父关系 

def demo_5():
    root = etree.XML("<root><a>TEXT</a></root>")
    find_text = etree.XPath("//text()")
    text = find_text(root)[0]
    print(text)
    print(text.getparent().text)

    # 禁用父关系
    find_text = etree.XPath("//text()", smart_strings=False)
    text = find_text(root)[0]
    print(text)
    hasattr(text, ‘getparent‘)   

  (4) list 或者 items

生成XPath表达式

ElementTree对象有一个getpath(element)方法,它返回一个结构的、绝对的XPath表达式来查找该元素:

def demo_6():
    a = etree.Element("a")
    b = etree.SubElement(a, "b")
    c = etree.SubElement(a, "c")
    d1 = etree.SubElement(c, "d")
    d2 = etree.SubElement(c, "d")
    tree = etree.ElementTree(c)
    print(tree.getpath(d2))  # /c/d[2]
    print(tree.xpath(tree.getpath(d2)) == [d2])

XPath类

XPath类将XPath表达式编译为可调用函数

def demo_7():
    root = etree.XML("<root><a><b/></a><b/></root>")
    find = etree.XPath("//b")
    print(find(root)[0].tag)

编译花费的时间和 xpath()方法相同,但是每个类实例化编译一次,这能提高重复计算相同 Xpath 表达式的效率。就像xpath()方法一样,XPpath类支持xpath变量

def demo_8():
    root = etree.XML("<root><a><b/></a><b/></root>")
    count_elements = etree.XPath("count(//*[local-name() = $name])")
    print(count_elements(root, name="a"))
    print(count_elements(root, name="b"))

这支持非常有效地计算XPath表达式的修改版本,因为编译仍然只需要一次。

前缀到命名空间的映射可以作为第二个参数传递:

def demo_9():
    root = etree.XML("<root xmlns=‘NS‘><a><b/></a><b/></root>")
    find = etree.XPath("//n:b", namespaces={‘n‘: ‘NS‘})
    print(find(root)[0].tag)

XPath中的正则表达式

默认情况下,XPath支持EXSLT名称空间中的正则表达式,也可以使用 regexp 关键字禁用它,默认值是 True

def demo_10():
    regexpNS = "http://exslt.org/regular-expressions"
    find = etree.XPath("//*[re:test(., ‘^abc$‘, ‘i‘)]", namespaces = {‘re‘: regexpNS})
    root = etree.XML("<root><a>aB</a><b>aBc</b></root>")
    print(find(root)[0].text)

后面还有一些看不下去了,下一篇写下 xpath 的常规用法,点击下载代码

原文地址:https://www.cnblogs.com/zimengfang/p/10141005.html

时间: 2024-08-30 14:59:46

Python爬虫从入门到进阶(4)之xpath的使用的相关文章

Python爬虫从入门到进阶(2)之爬虫简介

1.爬虫入门:使用代码模拟真实用户发送网络请求批量获取数据1).爬虫价值: 1.买卖数据(高端领域特别贵) 2.数据分析(出分析报告) 3.流量 4.阿里指数,百度指数2).合法性:灰色产业政府没有法律规定爬虫是否违法 公司概念:公司让你爬取数据 爬虫是否可以爬所有的东西?不可以,爬虫只能爬取到用户可以访问的数据 爱奇艺视频(vip 用户,非 vip 用户) 付费小说(付费才能爬取) 2.爬虫分类: 1.通用爬虫:使用搜索引擎:百度,360,谷歌... 劣势:目标不明确,返回的内容90%是用户不

Python爬虫从入门到进阶(1)之Python概述

1.计算机语言概述 (1).语言:交流的工具,沟通的媒介 (2).计算机语言:人跟计算机交流的工具 (3).Python是计算机语言的一种 2.Python编程语言 代码:人类的语言,同代码命令机器,跟机器交(2).python解释器:担任翻译工作(3)流程: 写代码 --> 执行:由翻译官(Python解释器)把命令(Code)翻译给机器,同时把机器结果翻译给我们 3.Python简史 (1).1989 (2).2008:Python 3.0 诞生 (3)2014:宣布2.7支持到2020年

Python 爬虫从入门到进阶之路(五)

在之前的文章中我们带入了 opener 方法,接下来我们看一下 opener 应用中的 ProxyHandler 处理器(代理设置). 使用代理IP,这是爬虫/反爬虫的第二大招,通常也是最好用的. 很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问. 所以我们可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取. urllib.request 中通过ProxyHandler来设置使用代理服

Python 爬虫从入门到进阶之路(十一)

之前的文章我们介绍了一下 Xpath 模块,接下来我们就利用 Xpath 模块爬取<糗事百科>的糗事. 之前我们已经利用 re 模块爬取过一次糗百,我们只需要在其基础上做一些修改就可以了,为了保证项目的完整性,我们重新再来一遍. 我们要爬取的网站链接是 https://www.qiushibaike.com/text/page/1/ . 我们通过 Xpath Helper 的谷歌插件经过分析获取到我们想要的内容为: //div[@class="content"]/span[

Python 爬虫从入门到进阶之路(十四)

之前的文章我们已经可以根据 re 模块,Xpath 模块和 BeautifulSoup4 模块来爬取网站上我们想要的数据并且存储在本地,但是我们并没有对存储数据的格式有要求,本章我们就来看数据的存储格式 JSON 及 Python 中的 json 模块. JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写.同时也方便了机器进行解析和生成.适用于进行数据交互的场景,比如网站前台与后台之间的数据交互. JSON和XML的比较

Python爬虫从入门到进阶(3)之requests的使用

快速上手(官网地址:http://www.python-requests.org/en/master/user/quickstart/) 发送请求 首先导入Requests模块 import requests 试着获取一个网页 r = requests.get('https://api.github.com/events') 返回的 r 是 Response 对象,可以从这个对象中获得所有信息. Requests 简单的 API 意味着所有 HTTP 请求类型都是显而易见的.例如,可以这样发送一

python爬虫-基础入门-爬取整个网站《3》

python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python2.x 使用类库: >> urllib 库 >> urllib2 库 python3.x 使用的类库: >> urllib 库 变化: -> 在python2.x中使用import urllib2 ----- 对应的,在python3.x 中会使用import url

python爬虫小小白入门

python爬虫小小白入门 学习目标: 爬虫基本思想 python爬虫常用包,官方文档,用途,安装方法,常用方法. 简单爬虫实例--从W3Cschool爬取C语言教程文本 python环境:: Anaconda3, spyder, windows10 一.基本思想 爬虫就是从网页上抓取你想要的内容,主要分为三个步骤.首先需要仔细分析目标页面内容,知道你想要的内容:文字,图片,视频在HTML中的哪个标签里,然后通过爬虫代码向服务器发起请求,得到HTML页面内容,最后把目标内容解析出来. 分析目标页

python爬虫从入门到精通-系列教程

开始爬虫之旅 引言 我经常会看到有人在知乎上提问如何入门 Python 爬虫?.Python 爬虫进阶?.利用爬虫技术能做到哪些很酷很有趣很有用的事情?等这一些问题,我写这一系列的文章的目的就是把我的经验告诉大家. 什么是爬虫? 引用自维基百科 网络蜘蛛(Web spider)也叫网络爬虫(Web crawler),蚂蚁(ant),自动检索工具(automatic indexer),或者(在FOAF软件概念中)网络疾走(WEB scutter),是一种“自动化浏览网络”的程序,或者说是一种网络机