抓取网站时,您通常需要根据文本内容选择页面上的元素。这使您可以精确定位要提取的数据。 XPath 是一种用于在 XML 和 HTML 文档中选择节点的查询语言,它提供了几种使用 contains()
和 text()
功能。
在本指南中,我们将深入了解如何在 XPath 表达式中利用这些文本选择技术。我们将介绍语法、演练示例并讨论一些最佳实践,以帮助您在网页抓取时根据文本内容有效地选择元素。
使用 contains() 选择包含文本的元素
X路径 contains()
函数允许您选择包含特定文本子字符串的元素。它需要两个参数:
- 要在其中搜索的节点集
- 要匹配的文本子字符串
语法如下:
//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 文本选择器进行网页抓取时,请记住以下提示:
请注意您尝试匹配的文本中的空格。额外的空格或换行符可能会导致选择器失败。使用 normalize-space() 删除前导和尾随空白,并根据需要折叠内部空白。
注意大小写。默认情况下,XPath 中的文本匹配区分大小写。使用 lower-case() 或 upper-case() 进行不区分大小写的匹配。
避免过于笼统的文本选择器,因为它们可能匹配非预期的元素。尝试将文本选择器与元素名称或属性结合起来,使它们更加具体。
始终根据真实的当前页面内容测试您的选择器。网站经常变化,因此如果文本内容已更新,昨天有效的选择器今天可能会失败。
如果网站的格式或用户生成的内容不一致,则文本选择器可能不可靠。在这些情况下,通常最好使用基于元素名称、属性或文档树中位置的结构选择器。
结论
XPath 提供了基于文本内容选择元素的强大方法,使用 contains()
和 text()
功能。 contains()
对于匹配包含特定文本子字符串的元素很有用,而 text()
按准确的全文内容选择元素。
当与其他 XPath 表达式结合使用时,这些文本选择器会更加有效,为网页抓取创建高度针对性的元素选择器。
不仅仅是 contains()
和 text()
,XPath 还有其他几个处理文本的有用函数,例如 starts-with()
, ends-with()
, normalize-space()
, 和更多。花一些时间学习 XPath 语法的这些部分和其他关键部分。
充分掌握 XPath 文本选择器后,您就能够从网页中精确定位和提取所需的数据。快乐刮擦!