Простой парсинг сайтов с помощью SlimerJS

В виду отсутствия хорошего материала по парсингу с помощью скриптового браузера SlimerJS и наличия свободного времени решил написать небольшую статью.



Начало работы


Для того, чтобы начать работать со SlimerJs, необходимо скачать последнюю версию скриптового браузера (я обычно качаю полную версию, в которую включен XulRunner, позволяющий запускать SlimerJS в отсутствие Firefox) для вашей ОС.

Не буду описывать инсталяцию SlimerJS, так как она довольно подробно описана здесь, поэтому сразу перейдем к разбору ситуаций, которые чаще всего могут встретиться при парсинге сайта с динамическм контентом.

Использование


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

var webpage = require('webpage').create();
webpage
  .open('http://example.com') 
  .then(function(){ 
	slimer.wait(3000); // пауза, длительность в миллисекундах
	var someContent = webpage.evaluate(function () { // после того как динамический контент подгружен, можно его спарсить
		return document.querySelector("#aDiv").textContent;
    });
  });


Еще одна полезная возможность — это создание событий. Очень просто имитировать набор символов в тексовом поле, что часто требуется при авторизации или регистрации, например:

var webpage = require('webpage').create();
webpage
  .open('http://example.com') 
  .then(function(){ 
	webpage.evaluate(function () { 
		document.getElementById("input").focus();
    });
	webpage.sendEvent('keypress', "hello World"); 
  });

Вообще функция senEvent() очень гибкая, подробнее о ней можно прочитать здесь.

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

var webpage = require('webpage').create();
webpage
  .open('http://example.com') 
  .then(function(){ 
	webpage.clipRect = { top: 14, left: 3, width: 400, height: 300 }; // для использования этой функции нам должны быть известно позиционирование каптчи
	var screen = webpage.renderBase64('png'); // обычно я кодирую изображение в base64, так его проще передать сторонему сервису
	var webpage2 = require('webpage').create(); // создаем второе соединени
	webpage2
	  .open('http://example2.com') 
	  .then(function(){  //...далее думаю уже должно быть понятно
  });

SlimerJS очень похож на PhantomJS, но самое важное отличие, которое хотелось бы отметить — это окно бразуера во время выполнения SlimerJS. Другими словами, отладка и разработка ведутся проще, чем с фантомом.

Итог


SlimerJS позволяет быстро и просто парсить сложные динамические сайты, которые обычным cUrl спарсить не получается.
Метки:
Поделиться публикацией
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 15
  • +1
    Спасибо за актуальную и нужную информацию, как раз искал похожее!
    А как у него обстоят дела с авторизацией и хранением куков? Есть ли опыт написания приложений для парсинга закрытых страниц? Стоит актуальная задача, cURL не подходит…
    • 0
      Все эти функции поддерживаются в полной мере, подробнее об этом здесь, опыт в парсинге закрытых страниц есть
      • 0
        Спасибо, будем пробовать! Поддержка прокси… Если удастся реализовать одну мысль — будет отдельная статья на хабре. Еще раз спасибо!
    • +1
      Использовал SlimerJS для хакквеста. Из минусов могу отметить только отсутствие поддержки CSP (в отличие от CutyCapt, который мои задачи решал успешно).
      • 0
        На Java (конкретно на Android) есть что-либо подобное?
        • 0
          SlimmerJS вещь хорошая — почти полноценный firefox с поддержкой скриптования из командной строки, его можно полноценно использовать для сложного парсинга закрытых страниц с JavaScript.
          Только с помощью него у меня получилось делать нормальные скрины с одного портала, CutyCapt и PhantomJS косячили со шрифтами.
          • 0
            Для меня самым большим плюсом является именно наличие интерфейса у SlimerJS, и хоть какая документация по API в отличие от того же PhantomJS, хотелось бы узнать, делали ли вы связку с CasperJS?
            • 0
              К сожалению, нет.
              • 0
                Я попробовал. Получилось, не без проблем, но получилось. Особо пока не могу ничего сказать… работает, удобно.
                • 0
                  я так понимаю ты еще phantomJS накатил? по моему CasperJS без него не работает
                  • 0
                    Нет, не накатывал.
                    1. Установил casperjs по инструкции без phantomjs.
                    2. В папке bin переименовал файл «casperjs.exe» в «casperjs_exe.exe».
                    3. Создал файл casperjs.bat с содержимым:
                      @echo off
                      casperjs_exe --engine=slimerjs %*
                      

                    4. Затем добавил slimerjs в PATH.
                    5. Отредактировал slimerjs.bat, шестую строку:
                      SET SLIMERDIR=%~dp0
                      

                      заменил на:
                      if not exist (%SLIMERDIR%) (
                          SET SLIMERDIR=%~dp0
                      )
                      

                    6. Запустил пример CasperJS:
                      var casper = require('casper').create();
                      
                      casper.start('http://casperjs.org/', function() {
                          this.echo(this.getTitle());
                      });
                      
                      casper.thenOpen('http://phantomjs.org', function() {
                          this.echo(this.getTitle());
                      });
                      
                      casper.run();
                      

                    7. PROFIT! — Всё заработало на Standalone Edition и Lightweight Edition.
            • 0
              Спасибо! Не знал про такой инструмент, теперь буду использовать =)
              • 0
                А он webdriver поддерживает? Точнее так. Как я понимаю, это firefox почти и там это есть. Поэтому вопрос, приходилось ли использовать его с webdriver?
                • 0
                  Как у него с параллельностью сессий для одного сайта? Например, в PhantomJS до версии 2 нельзя залогиниться на одном сайте под разными аккаунтами.
                  • 0
                    Можно, но надо указать разные пути хранения временных файлов, вроде.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.