Сегодня мы будем писать скрипт для парсинга различных ресурсов, использующих для передачи данных о событиях файлы в формате iCal. Формат этот был придуман компанией Apple и в настоящее время на многих сайтах вы можете экспортировать события из календаря сайта в этом формате. В этом случае вам не нужно будет скрапить сам сайт и его HTML, а только лишь файл в формате iCal.
Diggernaut нативно поддерживает этот формат и автоматически переводит его в XML. И далее мы можем работать с этими данными также как с обычной HTML страницей.
Давайте посмотрим как это работает на примере календаря Science Fiction Conventions, найденного мной на просторах сайта icalshare.com. Начнем с написания раздела с установками. На первом этапе нам нужно будет установить диггер в дебаг режим с уровнем 2. Только так мы сможем увидеть исходный код забранного нами файла с календарем. А исходный код нам нужен, чтобы написать навигационную логику к блокам с данными, которые мы ходим забрать.
Сам календарь находится по адресу: https://www.google.com/calendar/ical/lirleni%40gmail.com/public/basic.ics
Итак, начало нашего конфига будет таким:
---
config:
debug: 2
agent: Firefox
do:
- walk:
to: https://www.google.com/calendar/ical/lirleni%40gmail.com/public/basic.ics
do:
- stop
В этом коде мы устанавливаем уровень Debug в 2, конфигурируем парсер использовать Firefox как имя браузера и забираем iCal файл. Теперь нам нужно зайти в свой аккаунт на Diggernaut.com, выбрать существующий проект (или создать новый) и создать в нем новый диггер, где в качестве конфига использовать вышеуказанный код.
Удостоверимся, что парсер находится в Debug режиме (в колонке Status должно быть указано Debug). Если нет, то нужно перевести парсер в дебаг режим, выбрав его в колонке Status. После чего мы должны запустить его. Как только диггер отработает, мы можем просмотреть лог запуска нажав на соответствующую иконку.
<html>
<head></head>
<body>
<body_safe>
<event>
<alarmtime>0s</alarmtime>
<class>PUBLIC</class>
<created>2009-03-07 20:15:36 +0000 UTC</created>
<description>Gaming Convention</description>
<end>2011-01-31 00:00:00 +0000 UTC</end>
<id>2a994c3e3b80f5af6e8fa178a3af45d4</id>
<importedid>b82f342c-0b54-11de-b762-000d936372a6</importedid>
<location>Champaign IL (USA)</location>
<modified>2011-02-20 23:29:49 +0000 UTC</modified>
<rrule></rrule>
<sequence>4</sequence>
<start>2011-01-28 00:00:00 +0000 UTC</start>
<status>CONFIRMED</status>
<summary>WinterWar 38</summary>
<wholedauyevent>true</wholedauyevent>
</event>
<event>
<alarmtime>0s</alarmtime>
<class></class>
<created>2009-01-10 17:33:11 +0000 UTC</created>
<description>Gaming convention</description>
<end>2011-08-08 00:00:00 +0000 UTC</end>
<id>5c8f16d772ede097822e73a0c2e51c6c</id>
<importedid>356F0F0C-FE52-47A8-AEAB-8E78F57D4F52</importedid>
<location>Indianapolis IN</location>
<modified>2011-02-20 23:29:48 +0000 UTC</modified>
<rrule></rrule>
<sequence>10</sequence>
<start>2011-08-04 00:00:00 +0000 UTC</start>
<status>CONFIRMED</status>
<summary>GenCon</summary>
<wholedauyevent>true</wholedauyevent>
</event> ...
Как мы видим структура страницы разбита на блоки . Так что все, что нам остается — это пройти во все блоки event и забрать все поля из каждого такого блока. Итак, давайте выберем один блок и отформатируем его, чтобы было лучше видно какие поля мы будем забирать и какие фильтры будем использовать.
<event>
<alarmtime>0s</alarmtime>
<class>PUBLIC</class>
<created>2009-03-07 20:15:36 +0000 UTC</created>
<description>Gaming Convention</description>
<end>2011-01-31 00:00:00 +0000 UTC</end>
<id>2a994c3e3b80f5af6e8fa178a3af45d4</id>
<importedid>b82f342c-0b54-11de-b762-000d936372a6</importedid>
<location>Champaign IL (USA)</location>
<modified>2011-02-20 23:29:49 +0000 UTC</modified>
<rrule></rrule>
<sequence>4</sequence>
<start>2011-01-28 00:00:00 +0000 UTC</start>
<status>CONFIRMED</status>
<summary>WinterWar 38</summary>
<wholedauyevent>true</wholedauyevent>
</event>
Мы не будем забирать все поля, а заберем лишь summary, description, start datetime, end datetime и location. Сделать это очень просто, сначала мы заходим в блок event, создаем объект для наших данных, далее проходим в блоки полей, парсим данные и кладем из в поля нашего объекта. После чего сохраняем объект.
---
config:
agent: Firefox
do:
- walk:
to: https://www.google.com/calendar/ical/lirleni%40gmail.com/public/basic.ics
do:
- find:
path: event
do:
- object_new: event
- find:
path: summary
do:
- parse
- normalize:
routine: replace_substring
args:
\\: ''
- object_field_set:
object: event
field: summary
- find:
path: description
do:
- parse
- normalize:
routine: replace_substring
args:
\\: ''
- object_field_set:
object: event
field: description
- find:
path: location
do:
- parse
- normalize:
routine: replace_substring
args:
\\: ''
- object_field_set:
object: event
field: location
- find:
path: start
do:
- parse:
filter: (\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})
- object_field_set:
object: event
field: start_date
- find:
path: end
do:
- parse:
filter: (\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})
- object_field_set:
object: event
field: end_date
- object_save:
name: event
Давайте запишем наш готовый конфиг в диггер и запустим его. Когда он закончит работу, перейдем в раздел с данными и удостоверимся, что они в полном порядке. Там вы увидите нечто похожее на:
Item #1
start_date 2011-01-28 00:00:00
summary WinterWar 38
description Gaming Convention
end_date 2011-01-31 00:00:00
location Champaign IL (USA)
Item #2
start_date 2011-08-04 00:00:00
summary GenCon
description Gaming convention
end_date 2011-08-08 00:00:00
location Indianapolis IN
Item #3
start_date 2011-03-11 00:00:00
summary Madicon 20
description Science Fiction, with a large proportion of Gaming
end_date 2011-03-14 00:00:00
location Harrisonburg VA, USA
Теперь переведем наш диггер в режим Active чтобы мы смогли скачать данные (пока диггер находится в режиме Debug, вы не можете скачивать данные, только просматривать выборку данных). Снова запустим его, дождемся окончания выполнения, перейдем в раздел с данными и скачаем их в нужном нам формате. Также вы можетес качать и изучить пример в формате XLSX.
Как вы видите, парсить данные с iCal ресурсов используя возможности Diggernaut очень просто!