XPath в сравнении с селекторами CSS

Назначение выражений XPath и селекторов CSS

Да, мы только что сказали, что предполагаем, что вы уже имеете представление о том, что они делают, но если мы ошиблись в предположениях, то позвольте нам просто побаловать наших читателей кратким обзором.

Назначение выражений XPath и селекторов CSS заключается в предоставлении выразительного языка, позволяющего находить и выбирать элементы в XML- и HTML-документах. Предположим, что у нас есть следующая веб-страница:

<!doctype html>
<html>
    <head>
        <title>What is the DOM ?</title>
        <meta charset="utf-8" />
    </head>

    <body>
        <h1>DOM 101</h1>
        <p>Webscraping is awsome !</p>
        <p>Here is my <a href="https://www.scrapingbee.com/blog/">blog</a></p>
    </body>
</html>

А теперь мы хотим извлечь URL нашего анкорного тега, указывающего на ScrapingBee. Как мы можем это сделать?

Конечно, можно вручную разобрать всю HTML-строку (например, токенизировать все и проверить на наличие <a) или - если уже более изощренно - использовать регулярные выражения (например, <a\\s+href="([^"]+)), но все это - ручной разбор строки, а это редко бывает интересно. 

Именно в этом случае на помощь приходят селекторы XPath и CSS. В нашем примере мы можем получить доступ к тегу якоря с помощью следующего синтаксиса в XPath и CSS соответственно.​

История селекторов XPath и CSS

Обе технологии появились довольно давно. Они появились примерно в середине-конце 90-х годов прошлого века, и хотя во многих отношениях они очень и очень похожи - их можно считать двоюродными братьями или даже сестрами, - тем не менее, они имеют разное происхождение и разные первоначальные цели.

XPath: Хотя границы между HTML и XML, по общему признанию, всегда были несколько подвижны, HTML всегда был ориентирован на работу в Интернете, в то время как XML всегда был в первую очередь форматом структурированных документов для данных. Именно здесь и появился XPath. XPath был представлен одновременно с XML и имел целью предоставить язык запросов для XML. Он должен позволять быстро и легко получать доступ к информации внутри данного XML-документа, независимо от того, где он находится - в Интернете или в известной базе данных XML.

CSS: Селекторы CSS не были самостоятельным изобретением, а являются частью общей экосистемы CSS. Однако они являются ее неотъемлемой частью, поскольку обеспечивают основную функциональность - поиск того самого элемента (элементов), к которому будет применен блок объявления правила. В этом контексте селекторы CSS всегда были очень сильно (и почти исключительно) ориентированы на веб и веб-страницы.

В то время как XPath оставался (в основном) верен своему первоначальному назначению - созданию языка запросов к структурам XML-документов (к которым относится и HTML), CSS-селекторы со временем вышли за рамки использования только для стилизации и превратились в самостоятельную технологию запросов к веб-документам.

Как мы уже говорили, обе технологии практически идентичны по своим возможностям и имеют общие черты синтаксиса, однако между ними все же существует достаточно много различий, а также преимуществ и ограничений. Именно это мы и рассмотрим далее.

Преимущества и ограничения XPath

Вообще говоря, XPath является более сложным языком. Если вы можете реализовать запрос с помощью селекторов CSS, вы можете сделать то же самое с помощью XPath. Обратное не всегда возможно.

Например, одним из основных преимуществ XPath является его способность поддерживать двунаправленное обходное движение по дереву. Вы можете найти определенный элемент, а затем, используя ось parent, выбрать его родителя или даже предков. Несмотря на то, что селекторы CSS предлагают полуэквивалент в виде псевдокласса :has, это все равно далеко не XPath, поскольку он охватывает лишь ограниченный набор случаев использования, а его поддержка браузерами все еще весьма сомнительна.

Несмотря на то, что производительность в данном контексте обычно не играет большой роли, иногда производительность XPath может быть выше, чем у селекторов CSS. Это связано с тем, что некоторые CSS-селекторы используют XPath для внутренних целей и сначала преобразуют свои селекторы в XPath-выражения.

Одним из недостатков XPath, безусловно, является его более многословный синтаксис. Такие вещи, как классы HTML, должны быть указаны в виде атрибутов, в то время как CSS поддерживает их как, скажем так, первоклассных граждан в своем синтаксисе.

Плюсы и минусы
+ Поддержка двунаправленного перемещения по дереву (обращение к родительскому или предковому элементу)
+ Поддержка выбора не только элементов документа (т.е. атрибутов и содержимого)
+ Встроенные функции для различных вариантов использования (например, text(), count())
+ Поддержка абсолютных и относительных путей поиска

- Более подробный синтаксис

Преимущества и ограничения CSS-селекторов

Одним из основных преимуществ CSS-селекторов является их "естественность" в контексте Web. Если вы знакомы с веб-разработкой, то вы сразу же поймете, что такое CSS-селекторы, поскольку уже давно используете их при оформлении страниц.

В отличие от выражений XPath, селекторы CSS прекрасно понимают, что такое идентификаторы и классы HTML, и предоставляют элементы с собственным синтаксисом (например, #id & .class). По этой причине CSS-селектор можно считать чуть менее многословным (a#id против \/\/a[@id="id"]).

К ограничениям можно отнести тот факт, что CSS-селекторы работают только на уровне элементов. То есть, если необходимо извлечь ссылку из тега <a>, то с помощью CSS-селекторов можно найти только все соответствующие теги, а к атрибуту href придется обращаться на втором этапе, вне контекста CSS-селектора (например, tag.getAttribute("href")). XPath выражения позволяют и здесь получить прямой доступ к атрибутам (например, \/\/a\/@href).

Еще одним существенным ограничением является нисходящий подход, который означает, что дерево DOM можно обходить только в одном направлении и нельзя выбирать родительские элементы (например, `... для файловых систем). Хотя это, возможно, не самый распространенный вариант использования, все же бывают случаи, когда это может пригодиться, и при использовании селекторов CSS приходится искать какой-то обходной путь.

Плюсы и минусы
+ Веб-разработчики знакомы с синтаксисом
+ Идентификаторы и классы HTML являются гражданами первого класса (синтаксис хэша и точки)

- Можно выбирать только элементы (без атрибутов или содержимого)
- Не поддерживает восходящий обход (доступ к родительскому элементу или элементу-предку)
- Сложнее указать абсолютный путь поиска

Извлечение данных с помощью CSS-селекторов и ScrapingBee

На всякий случай, если вы еще не знакомы с сервисом извлечения данных ScrapingBee: это SaaS-платформа для извлечения данных с легким REST API, собственными SDK-пакетами для некоторых языков и поддержкой интеграции с безголовыми браузерами.
 
Несмотря на то, что XPath, несомненно, более совершенен для некоторых случаев использования, мир веб-парсинга в значительной степени определяется селекторами CSS, и пользователи, особенно веб-девелоперы, часто чувствуют себя более комфортно с ними, поэтому ScrapingBee решила поддерживать селекторы CSS в качестве основного языка выражения в API.
 
Запуск задания по извлечению данных довольно прост, и для этого достаточно предоставить JSON-объект с полями, которые вы хотите извлечь из страницы, в качестве параметра extract_rules. Например, следующий объект определяет два элемента извлечения ("title" и "subtitle") вместе с соответствующими CSS-селекторами (h1 для заголовка и #subtitle для подзаголовка).
{
"title": "h1",
"subtitle": "#subtitle"
}
В ответ вы получите аналогичный JSON-объект, содержащий поля с их значениями со страницы.