Манипулируем объектами
Используем хеш-таблицы
Хеш-таблицы используются как словари для очень многих целей, например вы можете создать словарь уже посещенных страниц и перед переходом на страницу, проверять были ли вы уже на ней. Также можно создавать референсные наборы данных для дальнейшей популяции объектов с данными. Хеш-таблицы нельзя использовать как подставные данные, но вы можете читать значения в регистр и работать с ними дальше.
Команда hashmap_set используется для записи значения поля хеш-таблицы из регистра (только в блоковом контексте) или напрямую:
# ПЕРЕХОДИМ В БЛОК
- find:
path: .somepath
do:
- parse
# ЗАПОЛНЯЕМ ЭЛЕМЕНТ ХЕШ-ТАБЛИЦЫ ЗНАЧЕНИЕМ РЕГИСТРА
- hashmap_set:
name: currency
field: EUR
# ЗАПОЛНЯЕМ ЭЛЕМЕНТ ХЕШ-ТАБЛИЦЫ ЗАДАННЫМ ЗНАЧЕНИЕМ
- hashmap_set:
name: currency
field: USD
value: United States Dollar
Команда hashmap_get используется для записи значения поля хеш-таблицы в регистр:
# ПЕРЕХОДИМ В БЛОК
- find:
path: .somepath
do:
# ЗАПОЛНЯЕМ РЕГИСТР ЗНАЧЕНИЕМ ЭЛЕМЕНТА ХЕШ-ТАБЛИЦЫ
- hashmap_get:
name: currency
field: EUR
Давайте посмотрим как можно использовать хэш-таблицу для предотвращения сбора данных о мероприятиях,
если регистрационный номер мероприятия дублируется. Исходный HTML для нашего сценария доступен
по этой ссылке.
Обратите внимание, мероприятие за номером 363101-09 дублируется в таблице, а нам требуется забрать лишь
первую встретившуюся запись и проигнорировать все последующие дубли идущие под этим же номером.
---
config:
debug: 2
agent: Firefox
do:
- walk:
to: https://www.diggernaut.com/sandbox/meta-lang-hash-table-ru.html
do:
- find:
# НАЙДЕМ ВСЕ ТЕГИ `tr`
path: tbody > tr
do:
# ОЧИСТИМ ПЕРЕМЕННУЮ РЕГИСТРАЦИОННОГО НОМЕРА МЕРОПРИЯТИЯ
- variable_clear: number
- find:
path: td.col2
do:
- parse
# СОХРАНИМ РЕГ. НОМЕР В ПЕРЕМЕННУЮ
- variable_set: number
# ПРОБУЕМ НАЙТИ РЕГ. НОМЕР В ХЭШ-ТАБЛИЦЕ И ИЗВЛЕЧЬ ПОЛЕ `name`
- hashmap_get:
name: <%number%>
field: name
- if:
# ЕСЛИ ПОЛЕ ЗАПОЛНЕНО ДАННЫМИ, ТО НИЧЕГО НЕ ДЕЛАЕМ
match: \S
# ЕСЛИ ПОЛЕ НЕ ЗАПОЛНЕНО ДАННЫМИ, ТО ЗАПИСЫВАЕМ ДАННЫЕ
else:
# СОЗДАЕМ НОВЫЙ ОБЪЕКТ `item`
- object_new: item
- find:
path: td.col3
do:
- parse
# СОХРАНЯЕМ РЕГ. НОМЕР В ХЭШ-ТАБЛИЦУ В ПОЛЕ `name` ДЛЯ
# ПОСЛЕДУЮЩИХ ПРОВЕРОК ДУБЛИКАТОВ
- hashmap_set:
name: <%number%>
field: name
# СОХРАНЯЕМ В ОБЪЕКТ ИМЯ МЕРОПРИЯТИЯ
- object_field_set:
object: item
field: name
- find:
path: td.col4
do:
- parse
# СОХРАНЯЕМ В ОБЪЕКТ МЕСТО ПРОВЕДЕНИЯ
- object_field_set:
object: item
field: location
- find:
path: td.col10
do:
- parse
# СОХРАНЯЕМ В ОБЪЕКТ СТАТУС МЕРОПРИЯТИЯ
- object_field_set:
object: item
field: isAvailable
# СОХРАНЯЕМ ДАННЫЕ
- object_save:
name: item
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Diggernaut | Мета-язык | Пример использования хеш-таблицы</title>
</head>
<body>
<div class="result-content">
<div>
<h3>363101 - Jr Golf Clinic Orange</h3>
</div>
<table cellspacing="2" border="1" cellpadding="5">
<thead>
<tr>
<th>Рег. номер</th>
<th>Описание</th>
<th>Место проведения</th>
<th>Статус</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col2">
<span class="nowrap">363101-07</span>
</td>
<td class="col3">Jr Golf-Orange 4,5:31</td>
<td class="col4">Randall Oaks Golf Cl</td>
<td class="col10">
<span class="success arstatus">Available</span>
</td>
</tr>
<tr>
<td class="col2">
<span class="nowrap">363101-09</span>
</td>
<td class="col3">Jr Golf-Orange 4,5:30</td>
<td class="col4">Randall Oaks Golf Cl</td>
<td class="col10">
<span class="success arstatus">Available</span>
</td>
</tr>
<tr>
<td class="col2">
<span class="nowrap">363101-09</span>
</td>
<td class="col3">Jr Golf-Orange 5,5:30</td>
<td class="col4">Randall Oaks Golf Cl</td>
<td class="col10">
<span class="success arstatus">Available</span>
</td>
</tr>
<tr>
<td class="col2">
<span class="nowrap">363101-10</span>
</td>
<td class="col3">Jr Golf-Orange 5,6:23</td>
<td class="col4">Randall Oaks Golf Cl</td>
<td class="col10">
<span class="success arstatus">Available</span>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
[
{
"item": {
"isAvailable": "Available",
"location": "Randall Oaks Golf Cl",
"name": "Jr Golf-Orange 4,5:31"
}
},
{
"item": {
"isAvailable": "Available",
"location": "Randall Oaks Golf Cl",
"name": "Jr Golf-Orange 4,5:30"
}
},
{
"item": {
"isAvailable": "Available",
"location": "Randall Oaks Golf Cl",
"name": "Jr Golf-Orange 5,6:23"
}
}
]
Далее мы рассмотрим насколько полезными могут быть счетчики и какие методы для них предусмотрены.