xpath用于HTML文档通过元素,理解HTML和XPath

本文介绍了从在浏览器中输入URL到页面显示的完整过程,涉及HTTP请求、HTML文档解析、DOM树构建以及浏览器如何根据DOM和CSS呈现页面。讨论了程序员选用机械键盘时红轴和茶轴的区别,并提供了XPath在网页抓取中的应用实例,强调了XPath选择器的灵活性和实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

5be53dba0b837.png

我们已经知道HTML是文本标记语言,那么HTML和浏览器有什么样的关系呢?

当我们在浏览器中输入URL到浏览器显示出页面的过程一般包括四个步骤:在浏览器输入URL。URL的第一部分(域名,比如baidu.com)用于在网络上找到合适的服务器,而URL以及cookie等其他数据则构成了一个请求,用于发送到那台服务器当中。

服务器端回应,向浏览器发送一个HTML页面。(也有可能发送的是json或者XML格式)

将HTML转换成为浏览器内部的树状表示形式:文档对象模型(Document Object Model,DOM)

基于一些布局规则渲染内部表示,达到我们在浏览器上看到的效果。

下面来看看这些步骤,以及他们所需要的文档表示。

URL

URL剩余的部分对于服务器端理解请求是什么非常重要。它可能是一张图片、一个文档,或是需要触发某个动作的东西,比如向服务器发送邮件。

HTML文档

服务器端读取URL,理解我们的请求是什么,然后回应一个HTML文档。该文档实质上就是一个文本文件,我们可以使用编辑器打开它。和大多数文本文档不同,HTML文档具有万维网联盟指定的格式。当我们在浏览器访问https://www.baidu.com的时候,可以右键选择查看源代码。

树表示法(DOM)

每个浏览器都有其复杂的内部数据结构,凭借它来渲染网页。DOM表示法具有跨平台、语言无关性等特点,并且被大多数浏览器支持。

想要在Chrome中查看网页的树表示法,可以选择一个元素然后右键检查。

6b66fd7ebd27fb69e2acb9f655776416.png

这个时候我们看到的这个东西就是HTML代码的树表示法。

HTML只是文本,而树表示法是浏览器内存里的对象。

浏览器

HTML文本表示和树表示并不是向我们通常在浏览器上看到的那种视图。那么,树表示法是如何映射到我们在浏览器上看到的东西呢?答案就是框模型。正如DOM树元素可以包含其他元素或文本一样,默认情况下,挡在屏幕上渲染时,每个元素的框白哦是同样也都包含其嵌入元素的框表示。从某种意义上来说,我们在浏览器上所看到的是原始HTML文档的二维表示—-树结构也以一种隐藏的方式作为该表示的一部分。

使用XPath选择HTML元素

前面已经介绍过XPath的基本语法:链接 在这儿就复习一下:

XPath表达式://标签1[@属性1 = “值”]//标签2[@属性2 = “值”]/…/text()

//a[@href]用来选择包含href属性的所有链接,

不加text()[email protected],可以对这个对象再次使用XPath,这也就是先抓大再抓小的策略。

提取文本使用text()

使用*符号来选择指定层级的所有元素

而在Scrapy中,我们在最后还要.extract这个属性才能提取出来元素。

接下来我们学习常见的XPath

重点:前面的XPath学习中我都不知道XPath还有这种语法:

对于大型文档,可能需要编写一个非常大的XPath表达式以访问指定元素。为了避免这一问题,可以使用”//语法”,它可以让你取得某一特定类型的元素,而无需考虑其所在的层次结构。比如,//p将会选择所有的p标签,而//a则会选择所有的链接。

//语法可以在层次结构中的任何地方使用,这非常有用。比如我们想找到div class = “test”下的p标签中的内容,这个div class = “test”下可能还有很多子标签,但我们需要的只是p标签的内容,就可以使用这个语法:

//div[@class=”test”]//p/text()

我们也可以选择div test下的子div test1中的所有p标签中的内容

//div[@class=”test”]/div[@class=”test1”]//p/text()

这个语法非常有用,有点相见恨晚的感觉,再写爬虫的时候,经常需要使用XPath来提取有用的信息。这个XPath通常会费好大劲才能分析出来该怎么写,要搞清楚我们需要的信息属于哪个标签,通常在网页源代码中,这种嵌套关系可能有很多层。现在有个这个语法,我们只需要找到包含我们需要的信息的标签,然后直接使用//语法来获得我们需要的标签,这要省不少事。

更加有用的是,它还拥有找到href属性中以一个特定子字符串起始或包含的能力。

//a[starts-with(@href,”http://www")]

//a[contains(@href,”baidu”)]

//a[not(contains(@href,”baidu”))]

这些就是XPath的函数,starts-with()函数表示以特定值开头,contains()函数表示属性包含特定值,not(contains())表示不包含某特定值。XPath有很多像这样的函数,可以在百度上找到,不过这些函数不经常使用,记清楚基础的XPath语法才是重中之重。

常见XPath实例

有一些XPath表达式,我们将会将常遇到:获取id为test的h1标签下的span中的text。

//h1[@id=”test”]/span/text()

获取id为toc的div标签内的无序列表中所有的链接

[email protected]素内所有h1标签下的文本,这两个属性可能在同一个class中,也可能在不同的class中

//*[contains(@class,”ltr”) and contains(@class,”ltr1”)]//h1/text()

XPath的contains函数可以让你选择包含指定类的所有元素。选择class属性值为infobox的表格中的第一张图片的URL。

//table[@class=”infobox”]//img[1][email protected]

//div[starts-with(@class,”reflist”)][email protected]

//*[text()=”test”]/../following-sibling::div//a

请注意该表达式非常脆弱,并且很容易无法使用,因为他对文档结果做了过多假设。

更稳定的XPath

我们在抓取网页时,网页经常会发生变化。有时网页结果也会发生变化,因为网站有人在维护。如果他们的HTML已某种方式发生变化时,我们要调整我们的XPath。我们在写XPath时尽量遵循以下原则,帮助我们减少重写XPath的可能性。避免使用数组索引,例如:

//*[@id=”posts”]/article/div/div[1]/p

我们从浏览器中copy出来的XPath中经常会包含大量数字,解决办法是找到一个最接近p标签的标签,找到一个可以使用的包含id或者class属性的元素,如:

//div[@class=”post-body”]/p

类并没有那么好用

使用class属性可以更加容易的精确定位元素,不过这些属性一般是用于通过css影响外观的,新词可能会由于网站布局的微小变更而产生变化。

有意义的面向数据的类要比具体的或者面向布局的类更好

我们在使用类选择标签时,首先要选择与内容相关的类,因为这样的类更加可靠。

ID通常是最稳定的

通常情况下,id属性是针对一个目标的最佳选择,因为该属性既有意义又与数据相关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值