跳到内容

如何在 XPath 中通过文本选择元素

抓取网站时,您通常需要根据文本内容选择页面上的元素。这使您可以精确定位要提取的数据。 XPath 是一种用于在 XML 和 HTML 文档中选择节点的查询语言,它提供了几种使用 contains()text() 功能。

在本指南中,我们将深入了解如何在 XPath 表达式中利用这些文本选择技术。我们将介绍语法、演练示例并讨论一些最佳实践,以帮助您在网页抓取时根据文本内容有效地选择元素。

使用 contains() 选择包含文本的元素

X路径 contains() 函数允许您选择包含特定文本子字符串的元素。它需要两个参数:

  1. 要在其中搜索的节点集
  2. 要匹配的文本子字符串

语法如下:

//element[contains(text(), "substring")]

这将选择所有 element 文本内容包含指定内容的节点 substring.

例如,考虑以下 HTML:

<ul>
  <li>Apples</li>
  <li>Oranges</li>
  <li>Pears and Grapes</li>
</ul>

全选 <li> 包含文本“and”的元素,您可以使用:

//li[contains(text(), "and")]

这将匹配第三个 <li> 元素,“梨和葡萄”。

contains() 函数默认区分大小写。要执行不区分大小写的匹配,您可以使用 lower-case() or upper-case() 标准化套管的功能:

//li[contains(lower-case(text()), "and")]

的一个关键特征 contains() 是子字符串匹配可以跨越子元素。例如,在此 HTML 中:

<p>
  Select <em>this</em> paragraph.
</p>

X路径 //p[contains(text(), "Select this")] 仍然会匹配 <p> 标签,即使“Select”和“this”由 <em> 子元素。

使用 text() 按精确文本选择元素

contains() 对于部分文本匹配很有用,有时您需要完全匹配整个文本内容。这就是 text() 函数进来了。它根据全文内容选择元素。

语法是:

//element[text()="exact text"]

例如,使用以下 HTML:

<div>
  <p>Hello world!</p>
  <p>Hello again</p>
</div>

XPath 表达式 //p[text()="Hello world!"] 只会选择第一个 <p> 元素。第二 <p> 元素不匹配,因为它的文本内容不完全是“Hello world!”。

不比 contains()是, text() 函数仅匹配元素的直接文本内容。它与子元素中的文本不匹配。例如, //div[text()="Hello world!"] 不会匹配上面 HTML 中的任何内容,因为 <div> 其本身不直接包含文本“Hello world!”。该文本位于 <p> 子元素。

喜欢 contains()是, text() 函数默认区分大小写。相同 lower-case() or upper-case() 解决方法可用于不区分大小写的匹配。

将文本选择器与其他 XPath 表达式相结合

当与 XPath 表达式的其他部分(例如标签名称、属性和位置选择器)结合使用时,文本选择器会变得更加强大。这使您可以创建非常有针对性的选择器,以准确地深入找到您需要的元素。

例如,您可以使用以下 XPath 来选择 <a> 链接文本中包含“click”一词的元素,但前提是它们还具有“cta-button”类:

//a[contains(text(), "click") and @class="cta-button"]

或者这个表达式来选择第三个 <p> 页面上的元素,但前提是其文本内容以“Introduction”开头:

//p[starts-with(text(), "Introduction")][3]

通过混合和匹配不同的 XPath 构造,您可以构建非常具体的选择器来处理几乎任何 Web 抓取场景。

使用 Python 库的文本选择器示例

让我们看一下将 XPath 文本选择器与常见 Python 网页抓取库结合使用的一些实际示例。

lxml 和 requests 的示例

import requests
from lxml import html

# Send a GET request to the webpage
page = requests.get(‘https://example.com‘)

# Parse the HTML content
tree = html.fromstring(page.content)

# Select all <a> elements that contain the text "click me"
links = tree.xpath(‘//a[contains(text(), "click me")]‘)

# Print the href attribute of each selected link
for link in links:
    print(link.get(‘href‘))

BeautifulSoup 的示例

import requests
from bs4 import BeautifulSoup

# Send a GET request to the webpage
page = requests.get(‘https://example.com‘)

# Parse the HTML content
soup = BeautifulSoup(page.content, ‘html.parser‘)

# Select the first <p> element that starts with the text "Introduction"
intro_para = soup.select_one(‘p[text^="Introduction"]‘)

print(intro_para.text)

以硒为例

from selenium import webdriver
from selenium.webdriver.common.by import By

# Launch a browser and navigate to the webpage
driver = webdriver.Chrome()
driver.get(‘https://example.com‘)

# Select the <button> element with the exact text "Submit"
submit_button = driver.find_element(By.XPATH, ‘//button[text()="Submit"]‘)

submit_button.click()

提示和最佳实践

使用 XPath 文本选择器进行网页抓取时,请记住以下提示:

  1. 请注意您尝试匹配的文本中的空格。额外的空格或换行符可能会导致选择器失败。使用 normalize-space() 删除前导和尾随空白,并根据需要折叠内部空白。

  2. 注意大小写。默认情况下,XPath 中的文本匹配区分大小写。使用 lower-case() 或 upper-case() 进行不区分大小写的匹配。

  3. 避免过于笼统的文本选择器,因为它们可能匹配非预期的元素。尝试将文本选择器与元素名称或属性结合起来,使它们更加具体。

  4. 始终根据真实的当前页面内容测试您的选择器。网站经常变化,因此如果文本内容已更新,昨天有效的选择器今天可能会失败。

  5. 如果网站的格式或用户生成的内容不一致,则文本选择器可能不可靠。在这些情况下,通常最好使用基于元素名称、属性或文档树中位置的结构选择器。

结论

XPath 提供了基于文本内容选择元素的强大方法,使用 contains()text() 功能。 contains() 对于匹配包含特定文本子字符串的元素很有用,而 text() 按准确的全文内容选择元素。

当与其他 XPath 表达式结合使用时,这些文本选择器会更加有效,为网页抓取创建高度针对性的元素选择器。

不仅仅是 contains()text(),XPath 还有其他几个处理文本的有用函数,例如 starts-with(), ends-with(), normalize-space(), 和更多。花一些时间学习 XPath 语法的这些部分和其他关键部分。

充分掌握 XPath 文本选择器后,您就能够从网页中精确定位和提取所需的数据。快乐刮擦!

加入谈话

您的电邮地址不会被公开。 必填带 *