Но всё изменилось, когда я встретил Гуся. Мир парсинга заиграл новыми красками. Под катом я хочу показать несколько простых примеров, которые могут помочь распарсить непростые сайты.
Кстати, написав парсер, Гусь решил снять фильм про это, пока что вы можете насладиться трейлером:
Как натравить Гуся на сайт
Всем известно, Гусь любит пощипать — травку, бабушку, гусынь… и конечно же сайты. Чтобы Гусь отложил свои дела и пощипал сайт для вас, необходимо просто указать ему дорогу.
На данный момент Гусь умеет парсить:
- внутри nodejs, используя PhantomJS;
- прямо в браузере (идеально если вы пишете плагин для браузера)
- используя селениум
Каждый из способов имеет свои плюшки и недостатки. Например, Phantom может работать на сервере, но в нем не очень удобно дебажить, запуск Гуся в браузере требует внешнего инструмента, который садит Гуся на сайт. Селениум является довольно универсальным решением, но на данный момент Гусь только учится его использовать.
Итак, чтобы запустить Гуся на сайт, прежде всего надо выбрать и создать среду обитания. Возможные среды:
- PhantomEnvironment
- BrowserEnvironment
- SeleniumEnvironment
В данной статье я буду рассматривать PhantomEnvironment, как наиболее развитый на данный момент.
import {
PhantomEnvironment,
Parser
} from 'goose-parser';
const env = new PhantomEnvironment({
url: 'http://www.gooseplanet.ru/'
});
const parser = new Parser({env});
Среда определяет точку входа Гуся — УРЛ начальной страницы сайта.
До парсинга
Зачастую, до того как мы начнем парсить нам необходимо выполнить какие-либо действия на странице. Например, поиск на гусином сайте знакомств. Гусь поищет за вас — только попросите.
const actions = [
{
type: 'type', // тип действия - печатать
text: 'гусыня', // Гусь будет искать гусынь, чтоб неплохо потоптаться
scope: '.field[name=search]' // селектор елемента
},
{
type: 'click',
scope: 'button[type=submit]',
waitForPage: true // если знаем что результаты откроются на новой странице
}
];
Декларативность — наше всё
Гусь описателен. Он прост и немногословен.
Пора бы и пощипать
Итак, теперь мы знаем, как найти гусынь. Пора стрельнуть у них адресок. Допустим верстка результатов поиска выглядит вот так:
<ul class="goose-babes">
<li class="goose-babe">
<img src="https://habrastorage.org/getpro/habr/post_images/3df/cbd/088/3dfcbd088e8f5b4ba060a73f8d5e3788.jpg" alt="Кряша" class="photo">
<span class="name">Кряша</span>
<div>
<address>Гусятник №5</address>
</div>
</li>
<li class="goose-babe">
<img src="https://habrastorage.org/getpro/habr/post_images/a48/283/87b/a4828387bbe8658749cc7a42d53ddcd9.jpg" alt="Гатильда" class="photo">
<span class="name">Гатильда</span>
<div>
<address>Хлев</address>
</div>
</li>
</ul>
Сориентируем Гуся, задав правила для расположения данных в этой верстке:
const rules = {
scope: '.goose-babe',
collection: [[
{
name: 'name',
scope: '.name'
},
{
name: 'address',
scope: 'address'
}
]]
};
Запускаем Гуся!!
parser.parse({ actions, rules }).then(console.log);
И получаем результат:
[
{
"name": "Кряша",
"address": "Гусятник №5"
},
{
"name": "Гатильда",
"address": "Хлев"
}
]
И это только начало
Конечно же данная статья лишь знакомит читателей с Гусем, а не описывает все его возможности. Подробно о том, что умеет Гусь можно прочитать в документации. Но все же давайте перечислим некоторые приемы, которые Гусь приберег для непростых ситуаций:
- Гусь не боится пагинации — он может скролить страницы или прокликивать ссылки для получения нового контента. Вы можете даже научить Гуся кастомной пагинации;
- Гусь умеет ходить между страницами, важно и грациозно;
- Гусь может выполнять необходимые действия с клавиатурой и мышью для получения конкретного кусочка информации — у него очень шустрые лапки;
- Гусь может преобразовать полученные результаты;
- Гусь — умное, интеллигентное животное, вы можете рассказать ему новые фишки для парсинга и он начнет их применять — API для Гусь-парсера очень легко расширяется;
- Гусь — животное общинное, за счет своей любви к nodejs, легко может жить на гусиной ферме и парсить миллионы сайтов единовременно;
Поставьте Гусю звезду — и он захватит мир ради вас github.com/redco/goose-parser
Комментарии (11)
Amareis
07.06.2016 12:16parser.parse({ actions, rules }).then(console.log);
Вот это разве не бросит исключение? Там вроде надо делать console.log.bind(console).
IvanPanfilov
07.06.2016 13:18+2{
type: 'type', // тип действия — печатать
text: 'гусыня', // Гусь будет искать гусынь, чтоб неплохо потоптаться
scope: '.field[name=search]' // селектор елемента
},
{
type: 'click',
scope: 'button[type=submit]',
waitForPage: true // если знаем что результаты откроются на новой странице
}
const rules = {
scope: '.goose-babe'
зачем изобретать новый язык?
и чем это лучше querySelector?
Demogor
13.06.2016 08:09Сама статья любопытна, стиль написания позабавил, спасибо.
Что до личного опыта — из всех инструментов для базового парсинга, которые пробовал, пока больше всего понравился NW.js/Electron. Из коробки можно подключить тот же jQuery(а можно и ванильной js'кой) и строить DOM-дерево со всеми последующими плюшками.
За счет контекста ноды легко контачится с Tor'ом, чуть сложнее — с Fiddler(что позволяет делать волшебные штуки вроде распределения списка прокси по каждому запросу либо изменений ответа сервера), из коробки умеет прокси/подмену заголовков(что тоже иногда весьма полезно) и прочие радости жизни. Отличная поддержка ES6 из коробки, все такое. Ну и визуальное отображение результатов/отладки никто не отменял, конечно же(удобно, когда приходится ковырять пакован обфусцированного js).
WST
Надеюсь, это не разработка Алексея Бабушкина?
GreyCat
Пока и из всей статьи, и из поверхностного чтения документации абсолютно непонятно, чем это лучше сотни имеющихся альтернатив. Более-менее понятно, чем хуже: хотя бы необходимостью изучать очередной новый API, механизм описания правил и т.д. Интересно, есть какие-то преимущества и killer features, ради чего нужно бросить Scrapy, Grab, pjscrape, EDF, harvest/jarvest, upton, или даже какую-то когорту более высокоуровневых инструментов, где не надо вручную писать правила?
ChALkeRx
Исходя из текста статьи, я так понял, что гусями.
Но в данный момент это претензия не к самой библиотеке, а скорее к методу подачи материала в статье. Код ещё не смотрел.
GreyCat
Я чуть-чуть посмотрел, пока чего-то суперинтересного не обнаружил. Масштабирования нет примерно никакого: ни слова о том, чтобы подключать какое-то внешнее хранилище URLов, индексы, очереди и т.д. Выживаемость, перезапускаемость и восстанавливаемость процесса тоже на первый взгляд примерно никакая: даже если очень захотелось и начал парсить пару миллионов страниц на одной машине и оно упало где-то в конце — начинаем все с самого начала. Автоматизации парсинга толком никакой не просматривается: для того, чтобы локализировать нужный кусок текста на странице нужно написать вручную некое декларативное описание координат вытаскиваемого. Никаких инструментов, чтобы генерировать такие штуки хотя бы визуально, тупо ткнув в браузере по элементу, вроде бы нет. Поддержки каких-то продвинутых методов стабилизации скачивания (поддержания собственного списка проксей, абьюзинг TOR ;), или хотя бы зацепления за ту же Crawlera) нет — есть максимум куцая ротация заранее заданного списка проксей.
Вопрос, что же там есть уникального, чего нет нигде, остается.