Проблемы с очисткой сайта с помощью zombie.js - PullRequest
9 голосов
/ 07 сентября 2011

Мне нужно кое-что почистить.Поработав с различными средами веб-тестирования, большинство из которых либо слишком медленные (Selenium), либо слишком глючные для моих нужд (env.js), я решил, что zombie.js выглядит наиболее многообещающе, так как он используетсолидный набор библиотек для разбора HTML и манипулирования DOM.Однако мне кажется, что он даже не поддерживает базовый код Javascript, основанный на событиях, как на следующей веб-странице:

<html>
  <head>
    <title>test</title>
    <script type="text/javascript">

      console.log("test script executing...");
      console.log("registering callback for event DOMContentLoaded on " + document);

      document.addEventListener('DOMContentLoaded', function(){
        console.log("DOMContentLoaded triggered");
      }, false);

      function loaded() {
        console.log("onload triggered");
      }

    </script>
  </head>

  <body onload="loaded();">
    <h1>Test</h1>
  </body>
</html>

Затем я решил вручную запустить эти события, например:

zombie = require("zombie");

zombie.visit("http://localhost:4567/", { debug: true }, function (err, browser, status) {

  doc = browser.document;
  console.log("firing DOMContentLoaded on " + doc);
  browser.fire("DOMContentLoaded", doc, function (err, browser, status) {

    body = browser.querySelector("body");
    console.log("firing load on " + body);
    browser.fire("load", body, function (err, browser, status) {

      console.log(browser.html());

    });
  });

});

, который работает для этой конкретной тестовой страницы.Однако моя проблема носит более общий характер: я хочу иметь возможность просматривать более сложные сайты на основе AJAX, например, список друзей в Facebook (что-то вроде http://www.facebook.com/profile.php?id=100000028174850&sk=friends&v=friends).. Нет проблем, чтобы войти на сайт с помощью зомби., но некоторый контент, такой как эти списки, кажется, полностью загружается динамически с использованием AJAX, и я не знаю, как вызвать обработчики событий, которые инициируют загрузку.

У меня есть несколько вопросов относительно этой проблемы:

  • Кто-нибудь уже внедрил подобный сложный скребок без использования решения удаленного управления браузером, такого как Selenium?
  • Есть ли какая-нибудь ссылка на процесс загрузки сложной страницы на основе Javascript?
  • Может ли кто-нибудь дать совет о том, как отладить настоящий браузер, чтобы посмотреть, что мне может понадобиться для запуска обработчиков событий Facebook?
  • Есть еще идеи по этой теме?

Опять же, пожалуйста, не указывайте мне на решения, связанные с управлением реального браузера, такого как Selenium,как я знаю о тех.Однако приветствуются предложения для реального рендерера в памяти, такого как WebKit, доступного на языке сценариев Ruby, но предпочтительно с возможностью установки файлов cookie и предпочтительно также загрузки необработанного HTML вместо запуска реальных HTTP-запросов.

1 Ответ

13 голосов
/ 07 сентября 2011

В целях извлечения данных запустить «безголовый браузер» и вручную запускать события javascript не будет самым легким делом. Хотя это не невозможно, существуют более простые способы сделать это.

Большинство сайтов, даже AJAX-тяжёлых, можно очистить, не выполняя ни одной строки их кода Javascript. На самом деле обычно проще, чем пытаться выяснить Javascript-код сайта , который часто запутывается, минимизируется и его трудно отладить. Если вы хорошо разбираетесь в HTTP, вы поймете, почему: (почти) все взаимодействия с сервером кодируются как HTTP-запросы, независимо от того, инициируются ли они Javascript, или пользователь щелкает ссылку, или пользовательский код в программе бота, нет никакой разницы с сервером. (Я говорю почти потому, что когда Flash или апплеты вовлекаются, невозможно сказать, куда и куда летят данные; они могут зависеть от приложения. Но все, что делается в Javascript, будет проходить через HTTP.)

При этом можно подражать пользователю на любом веб-сайте, используя специальное программное обеспечение. Сначала вы должны увидеть необработанные HTTP-запросы, отправляемые на сервер. Вы можете использовать прокси-сервер для записи запросов, сделанных реальным браузером на целевой веб-сайт. Существует множество инструментов, которые вы можете использовать для этого: Charles или Fiddler - удобные, наиболее специализированные инструменты для скрининга экрана имеют базовый встроенный прокси, Расширение Firebug для Firefox и Chrome имеет похожие инструменты для просмотра AJAX-запросов ... Вы понимаете.

Как только вы можете увидеть HTTP-запросы, сделанные в результате определенного действия на веб-сайте, можно легко написать программу, имитирующую эти запросы; просто отправьте те же запросы на сервер, и он будет обрабатывать вашу программу так же, как браузер, в котором было выполнено определенное действие.

Существуют разные библиотеки для разных языков, предлагающие разные возможности. Что касается рубина, я видел много людей, использующих механизму для рубина .

Если извлечение данных является вашей единственной целью, то вы почти всегда сможете получить то, что вам нужно, имитируя HTTP-запросы таким образом. Javascript не требуется.

Примечание - Поскольку вы упомянули Facebook, я должен упомянуть, что удаление Facebook специально может быть исключительно трудным (хотя и не невозможным), потому что Facebook имеет меры для обнаружения автоматического доступа (они используют больше, чем просто капчи). ); они отключат учетную запись, если увидят подозрительную активность, исходящую от нее. Это, в конце концов, против их условий обслуживания (раздел 3.2).

...