Python中利用xpath解析HTML的方法

2023-11-08

本文主要介绍了Python中利用xpath解析HTML的方法,利用其lxml.html的xpath对html进行分析,获取抓取信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在进行网页抓取的时候,分析定位html节点是获取抓取信息的关键,目前我用的是lxml模块(用来分析XML文档结构的,当然也能分析html结构), 利用其lxml.html的xpath对html进行分析,获取抓取信息。

首先,我们需要安装一个支持xpath的python库。目前在libxml2的网站上被推荐的python binding是lxml,也有beautifulsoup,不嫌麻烦的话还可以自己用正则表达式去构建,本文以lxml为例讲解。

假设有如下的HTML文档:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<html>

 <body>

  <form>

   <div id='leftmenu'>

    <h3>text</h3>

    <ul id='china'><!-- first location -->

     <li>...</li>

     <li>...</li>

       ......

    </ul>

    <ul id='england'><!-- second location-->

     <li>...</li>

     <li>...</li>

       ......

    </ul>

   </div>

  </form>

 </body>

</html>

直接使用lxml处理:

1

2

3

4

5

6

import codecs

from lxml import etree

f=codecs.open("ceshi.html","r","utf-8")

content=f.read()

f.close()

tree=etree.HTML(content)

etree提供了HTML这个解析函数,现在我们可以直接对HTML使用xpath了,是不是有点小激动,现在就尝试下吧。

在使用xpath之前我们先来看看作为对照的jQuery和RE。

在jQuery里要处理这种东西就很简单,特别是假如那个ul节点有id的话(比如是<ul id='china'>):

1

$("#china").each(function(){...});

具体到此处是:

代码如下:

$("#leftmenu").children("h3:contains('text')").next("ul").each(function(){...});

找到id为leftmenu的节点,在其下找到一个内容包含为”text”的h3节点,再取其接下来的一个ul节点。

在python里要是用RE来处理就略麻烦一些:

1

2

3

4

5

6

block_pattern=re.compile(u"<h3>档案</h3>(.*?)<h3>", re.I | re.S)

m=block_pattern.findall(content)

item_pattern=re.compile(u"<li>(.*?)</li>", re.I | re.S)

items=item_pattern.findall(m[0])

for i in items:

  print i

那么用xpath要怎么做呢?其实跟jQuery是差不多的:

1

nodes=tree.xpath("/descendant::ul[@id='china']")

当然,现在没有id的话也就只能用类似于jQuery的方法了。完整的xpath应该是这样写的(注意,原文件中的TAG有大小写的情况,但是在XPATH里只能用小写):

代码如下:

nodes=tree.xpath(u"/html/body/form/div[@id='leftmenu']/h3[text()='text']/following-sibling::ul[1]")

更简单的方法就是像jQuery那样直接根据id定位:

1

nodes=tree.xpath(u"//div[@id='leftmenu']/h3[text()='text']/following-sibling::ul[1]")

这两种方法返回的结果中,nodes[0]就是那个“text”的h3节点后面紧跟的第一个ul节点,这样就可以列出后面所有的ul节点内容了。

如果ul节点下面还有其他的节点,我们要找到更深节点的内容,如下的循环就是把这些节点的文本内容列出:

1

2

3

nodes=nodes[0].xpath("li/a")

for n in nodes:

  print n.text

对比三种方法应该可以看出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节点。

以上就是本文的全部内容,希望对大家的学习有所帮助。

转自:微点阅读   https://www.weidianyuedu.com

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python中利用xpath解析HTML的方法 的相关文章

随机推荐

  • LaTex使用技巧20:LaTex修改公式的编号和最后一行对齐

    写论文发现公式编号的格式不对 要求是如果是多行的公式 公式编号和公式的最后一行对齐 我原来使用的是 equation 环境 begin equation begin aligned a b c c d end aligned end equ
  • Unity中相机拍照并保存下来脚本

    以下是一个示例的Unity拍照脚本 用于拍摄相机看到的内容并保存在工程根目录下 using System using UnityEngine using System IO public class CameraCapture MonoBe
  • 八邻域断点检测

    八邻域断点检测 本文的理论思想主要来源大家可以参照 迈克老狼2012 OpenCV学习 13 细化算法 1 本文是我自己尝试着将八邻域的细化思想 运用到断点检测上 个人觉得其实仅仅是八邻域应用的一小方面大家可以尝试着往其他方面应用 其实相对
  • Linux SPI 总线 和设备驱动架构之三:SPI控制器驱动

    通过第一篇文章 我们已经知道 整个SPI驱动架构可以分为协议驱动 通用接口层和控制器驱动三大部分 其中 控制器驱动负责最底层的数据收发工作 为了完成数据收发工作 控制器驱动需要完成以下这些功能 1 申请必要的硬件资源 例如中断 DMA通道
  • Photoshop提示暂存盘已满怎么办?ps暂存盘已满如何解决?

    打开ps软件提示暂存盘已满是什么意思 如何解决Photoshop提示暂存盘已满 本文给大家带来了解决办法 一起来看看吧 如果遇到 暂存盘已满 错误 通常意味着用作暂存盘的硬盘 或驱动器 用尽了执行任务所需的存储空间 解决方案 方法一 释放更
  • spring中的那一堆Configuration

    EnableAutoConfiguration 开启Spring Application Context自动配置 系统会根据你引入的jar包情况 自动配置一些需要的bean 参考spring boot autoconfigure jar 下
  • python典型案例:打印输出九九乘法表

    python典型案例 打印输出九九乘法表 使用for循环语句打印输出代码如下 for x in range 1 10 外循环控制行数 for y in range 1 x 1 内循环控制列 print x y x y end end表示 为
  • Styled-component 入门使用(一)

    Styled component 入门使用 一 styled components 优点 自动引入关键 styled components可以跟踪哪些组件在页面上呈现 并注入其样式 可以实现加载所需的最小代码 不会产生类名冲突 styled
  • 反向代理服务器:nginx

    1 什么是nginx Nginx engine x 是一个高性能的 HTTP 和 反向代理web服务器 其特点是占有内存少 并发能力强 事实上nginx的并发能力在同类型的网页服务器中表现较好 能够支持高达 50 000 个 并发连接数 的
  • LED灯条亮度色温调节

    一般LED灯条为12V或者24V供电 恒压驱动 由于LED灯条中已经内嵌了限流电阻 因此不需要使用复杂的恒流措施 对LED灯条进行色温和亮度的调节 可以通过PWM来开关MOS管 正白4000 4500K或者暖白3000 3500K 1 恒流
  • Linux常用命令(帮助命令、用户管理命令和压缩解压命令)

    详细目录 帮助命令 man whatis apropos help 用户管理命令 useradd passwd who w 压缩解压命令 gzip gunzip tar zip unzip bzip2 bunzip2 帮助命令 man 功能
  • 全球与中国移动健康传感器市场未来发展趋势及十四五投资战略规划研究报告2021-2027年版

    2020年 全球移动健康传感器市场规模达到了 亿元 预计2027年将达到 亿元 年复合增长率 CAGR 为 本报告研究全球与中国市场移动健康传感器的产能 产量 销量 销售额 价格及未来趋势 重点分析全球与中国市场的主要厂商产品特点 产品规格
  • 为什么要重写hashCode和equals方法【深入分析版】

    在回答这个问题前 我们先来看看Object类中的这两个方法 public native int hashCode public boolean equals Object obj return this obj 其中hashCode调用的是
  • 界面设计软件都有哪些?推荐这7款

    本文总结了7种 知名 软件界面设计工具 建议您尝试各种选择 以找到最适合您的UI设计工具 对于UI设计师来说 应用程序的界面设计和制作是最常见的 面对设计师的需求 市场上出现了各种各样的软件界面设计工具 百花齐放的情况不禁让设计师们大吃一惊
  • 异常eclipse Hadoop Failed to set permissions of path的解决

    eclipse Hadoop Failed to set permissions of path window下在eclipse中执行hadoop程序时报错 如下 原因文末有写 来自网友 所有的解决方案都是修改FileUitl文件 然后重新
  • 串口 同步和异步 理解

    串口 同步和异步 理解 https blog csdn net cs74184235 article details 48438727 本文主要三大块 一 串口同步和异步在底层通信上的区别 这部分点到为止 不是主要探讨内容 有个基本理解即可
  • 信捷plc,9伺服通用程序架构

    信捷plc 9伺服通用程序架构 程序已经升级 程序高度模块化 可轻易拓展十几二十多个轴 plc是目前性价比最高的方案 60个点10轴高速脉冲输出 走s形 正弦曲线加减速 程序采用C语言 梯形图架构 玩转信捷系统 可运用于三菱 西门子 欧姆龙
  • 小游戏 《唐僧大战白骨精》

    小游戏 唐僧大战白骨精 有点小无语的小游戏 当时做的还挺认真的 rint 欢迎光临 xxx 游戏 n 请选择你的身份 n 1 唐僧 n 2 白骨精 n sf input 请选择 1 2 if sf 1 print 你已经选择了1 你将以 g
  • pandas写入字典,或者pandas以各种格式输出数据

    1 将字典列表写入到pandas import pandas as pd rows buyer percent 23 2 tier city 1 buyer percent 18 54 tier city 2 df pd DataFrame
  • Python中利用xpath解析HTML的方法

    本文主要介绍了Python中利用xpath解析HTML的方法 利用其lxml html的xpath对html进行分析 获取抓取信息 具有一定的参考价值 感兴趣的小伙伴们可以参考一下 在进行网页抓取的时候 分析定位html节点是获取抓取信息的