При парсинге веб-сайтов часто приходится выбирать элементы на странице на основе их текстового содержимого. Это позволяет вам точно нацеливать данные, которые вы хотите извлечь. XPath, язык запросов для выбора узлов в документах XML и HTML, предоставляет несколько способов сделать это с помощью contains()
и text()
функции.
В этом руководстве мы подробно рассмотрим, как использовать эти методы выделения текста в выражениях XPath. Мы рассмотрим синтаксис, рассмотрим примеры и обсудим некоторые рекомендации, которые помогут вам эффективно выбирать элементы по их текстовому содержимому при парсинге веб-страниц.
Использование contains() для выбора элементов, содержащих текст
XPath contains()
Функция позволяет выбирать элементы, содержащие определенную текстовую подстроку. Требуется два аргумента:
- Набор узлов для поиска внутри
- Текстовая подстрока, которая соответствует
Синтаксис выглядит так:
//element[contains(text(), "substring")]
Это выберет все element
узлы, текстовое содержимое которых содержит указанное substring
.
Например, рассмотрим следующий HTML-код:
<ul>
<li>Apples</li>
<li>Oranges</li>
<li>Pears and Grapes</li>
</ul>
Выбрать все <li>
элементы, содержащие текст «и», вы должны использовать:
//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>
XPath //p[contains(text(), "Select this")]
все равно будет соответствовать <p>
тег, хотя «Выбрать» и «это» разделены тегом <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>
элемент не соответствует, поскольку его текстовое содержимое не совсем «Привет, мир!».
В отличие от contains()
, text()
Функция соответствует только прямому текстовому содержимому элемента. Он не соответствует тексту внутри дочерних элементов. Например, //div[text()="Hello world!"]
не будет соответствовать чему-либо в приведенном выше HTML, потому что <div>
сам по себе не содержит текста «Привет, мир!». Этот текст находится внутри <p>
дочерний элемент.
Подобно contains()
, text()
функция по умолчанию чувствительна к регистру. Одинаковый lower-case()
or upper-case()
обходной путь можно использовать для сопоставления без учета регистра.
Объединение селекторов текста с другими выражениями XPath
Селекторы текста становятся еще более мощными в сочетании с другими частями выражений XPath, такими как имена тегов, атрибуты и позиционные селекторы. Это позволяет вам создавать очень целевые селекторы для детализации именно тех элементов, которые вам нужны.
Например, вы можете использовать следующий XPath для выбора <a>
элементы, содержащие слово «click» в тексте ссылки, но только если они также имеют класс «cta-button»:
//a[contains(text(), "click") and @class="cta-button"]
Или это выражение для выбора третьего <p>
элемент на странице, но только если его текстовое содержимое начинается с «Введение»:
//p[starts-with(text(), "Introduction")][3]
Смешивая и сопоставляя различные конструкции XPath, вы можете создавать очень специфические селекторы для обработки практически любого сценария веб-скрапинга.
Примеры выбора текста с библиотеками Python
Давайте рассмотрим некоторые практические примеры использования селекторов текста XPath с распространенными библиотеками веб-скрапинга Python.
Пример с lxml и запросами
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 чувствительно к регистру. Используйте нижний регистр() или верхний регистр() для сопоставления без учета регистра.
Избегайте слишком общих селекторов текста, поскольку они могут соответствовать непредусмотренным элементам. Попробуйте объединить селекторы текста с именами элементов или атрибутами, чтобы сделать их более конкретными.
Всегда проверяйте свои селекторы на реальном, текущем содержимом страницы. Веб-сайты часто меняются, поэтому селекторы, которые работали вчера, сегодня могут дать сбой, если текстовое содержимое было обновлено.
Если веб-сайт имеет противоречивое форматирование или пользовательский контент, селекторы текста могут быть ненадежными. В таких случаях часто лучше использовать структурные селекторы на основе имен элементов, атрибутов или положения в дереве документа.
Заключение
XPath предоставляет мощные способы выбора элементов на основе их текстового содержимого, используя contains()
и text()
функции. contains()
полезен для сопоставления элементов, содержащих определенную текстовую подстроку, в то время как text()
выбирает элементы по их точному полнотекстовому содержимому.
Эти селекторы текста становятся еще более эффективными в сочетании с другими выражениями XPath для создания узконаправленных селекторов элементов для парсинга веб-страниц.
Помимо просто contains()
и text()
, XPath имеет несколько других полезных функций для работы с текстом, таких как starts-with()
, ends-with()
, normalize-space()
, и более. Потратьте некоторое время на изучение этих и других ключевых частей синтаксиса XPath.
Хорошо разбираясь в селекторах текста XPath, вы уже на пути к тому, чтобы точно нацеливать и извлекать нужные данные с веб-страниц. Приятного скрежетания!