Архив

Xpath в Datacol: продвинутый уровень. Часть 2

Xpath в Datacol: продвинутый уровень. Часть 2

В этой части продолжаем разбирать реальные ситуации, с которыми сталкиваются при парсинге сайтов в Datacol.
Мы рассмотрим, как использовать логические условия, функции поиска по началу и концу строки, очистку текста, навигацию по дереву элементов и сбор множественных значений.

Объединение условий (and, or)

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

HTML пример:

<div class="product" data-id="153">
  <a href="/catalog/item-1" class="link">Подробнее</a>
</div>
<div class="product">
  <a href="/sale/item-2" class="link">Подробнее</a>
</div>
<div class="news">
  <a href="/blog/post-1" class="link">Читать</a>
</div>

XPath:

//div[@class='product' and @data-id]//a

👉 Находит все ссылки внутри блоков product, у которых есть атрибут data-id.

XPath (вариант с or):

//a[contains(@href, '/catalog') or contains(@href, '/sale')]

👉 Выбирает все ссылки, которые ведут либо в раздел /catalog, либо /sale.

Поиск по началу и концу строки (starts-with(), ends-with())

Позволяет находить элементы, когда атрибуты формируются динамически, например, при генерации ID.

HTML пример:

<div>
  <span id="price_101">1990 ₽</span>
  <span id="price_102">2590 ₽</span>
  <span id="old_price">2990 ₽</span>
  <img src="/images/item-1.jpg">
  <img src="/images/item-2.png">
</div>

XPath с starts-with:

//span[starts-with(@id, 'price_')]

👉 Выберет только элементы, где id начинается с price_ (в нашем примере — первые два <span>).

XPath с ends-with:

//img[substring(@src, string-length(@src)-3) = '.jpg']

В XPath 1.0 (который использует Datacol) нет функции ends-with(),
поэтому используем обходное решение через substring().
Этот запрос найдёт все изображения, у которых имя файла оканчивается на .jpg.

Очистка текста с помощью normalize-space()

Иногда HTML-код содержит лишние пробелы и переносы, из-за чего поиск по тексту не срабатывает.
normalize-space() убирает лишние пробелы и переводит строку в аккуратный вид.

HTML пример:

<table>
  <tr>
    <td> Вес </td>
    <td> 2.5 кг </td>
  </tr>
  <tr>
    <td> Цвет </td>
    <td> Серый </td>
  </tr>
</table>

XPath:

//td[normalize-space(text())='Вес']/following-sibling::td[1]/text()

👉 Найдёт ячейку с текстом «Вес»,
затем перейдёт к следующей ячейке в строке (following-sibling::td[1])
и вернёт значение — 2.5 кг.

Навигация по дереву: ancestor::, following::, preceding::

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

<div class="card">
  <h2>Характеристики</h2>
  <table>
    <tr><td>Мощность</td><td>800 Вт</td></tr>
  </table>
</div>

<div id="breadcrumbs">
  <a href="/">Главная</a> › <a href="/catalog">Каталог</a>
</div>

<a class="active" href="/catalog/item-1">Товар</a>
<ul class="menu">
  <li><a href="/">Главная</a></li>
  <li><a href="/catalog">Каталог</a></li>
</ul>

Примеры XPath:

//h2[text()='Характеристики']/following::table[1]//tr

👉 Найдёт таблицу, которая следует сразу после заголовка «Характеристики».

//div[@id='breadcrumbs']/preceding::h2[1]

👉 Найдёт ближайший h2, который находится перед блоком с id='breadcrumbs'.

//a[@class='active']/ancestor::ul

👉 Поднимется вверх по дереву и найдёт родительский список <ul> для активной ссылки.

Сбор множественных значений (массивы)

Когда на странице несколько однотипных элементов (например, размеры, цвета, опции),
нужно собрать их в одном поле Datacol, настроив его как статическое.

HTML пример:

<ul class="sizes">
  <li>S</li>
  <li>M</li>
  <li>L</li>
  <li>XL</li>
</ul>

<select name="color">
  <option disabled>Выберите цвет</option>
  <option>Белый</option>
  <option>Черный</option>
  <option>Красный</option>
</select>

XPath для списка размеров:

//ul[@class='sizes']/li/text()

👉 Собирает все значения размеров (S, M, L, XL) в массив.

XPath для доступных цветов:

//select[@name='color']/option[not(@disabled)]/text()

👉 Собирает все значения <option>, кроме тех, где есть атрибут disabled.

💡 Советы по использованию

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

Рекомендую также ознакомится с первым материалом по Xpath для Datacol.

Нужна доработка или готовое решение?

Опишите задачу — отвечу в течение дня и назову сроки и стоимость.

Оставить комментарий