2011-09-07 16 views
8

Potrzebuję wykonać skrobanie w Internecie. Po zabawie z różnymi frameworkami do testowania stron internetowych, z których większość jest albo zbyt wolna (Selenium), albo zbyt niepoprawna dla moich potrzeb (env.js), zdecydowałem, że najbardziej obiecująca jest wersja zombie.js, ponieważ używa ona stałego zestawu bibliotek do analizy parsowania HTML i manipulacja DOM. Jednak wydaje mi się, że nawet nie obsługiwać podstawowe opartego na zdarzeniu kod Javascript, jak w poniższej stronie internetowej:Problemy ze skrobaniem witryny za pomocą zombie.js

<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> 

I wtedy postanowił wyzwolić te wydarzenia ręcznie tak:

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()); 

    }); 
    }); 

}); 

Która działa dla tej konkretnej strony testowej. Mój problem jest jednak bardziej ogólny: chcę być w stanie zadrapać bardziej złożone witryny oparte na AJAX, takie jak lista znajomych na Facebooku (coś w stylu: http://www.facebook.com/profile.php?id=100000028174850&sk=friends&v=friends). Nie ma problemu z zalogowaniem się do witryny za pomocą zombie, ale niektóre treści, takie jak te, wydają się być całkowicie załadowane dynamicznie przy użyciu AJAX i nie wiem, jak wywołać procedury obsługi zdarzeń inicjujące ładowanie.

Istnieje kilka pytań mam odnośnie tego problemu:

  • Czy ktoś już wdrożyła kompleksowy skrobaczki podobnie bez użycia przeglądarki zdalnej kontroli rozwiązanie jak selen?
  • Czy istnieje odniesienie do procesu ładowania złożonej strony opartej na Javascript?
  • Czy ktoś może doradzić, jak debugować prawdziwą przeglądarkę, aby zobaczyć, co może być konieczne do uruchomienia funkcji obsługi zdarzeń Facebook?
  • Jakieś inne pomysły na ten temat?

Jeszcze raz proszę, nie kierujcie mnie do rozwiązań dotyczących kontrolowania prawdziwej przeglądarki, takiej jak Selenium, o czym ja wiem. Jednakże mile widziane są sugestie dotyczące prawdziwego mechanizmu renderowania w pamięci, takiego jak WebKit, dostępnego z języka skryptowego Ruby, ale preferowanie z możliwością ustawienia plików cookie i preferowane jest również ładowanie nieprzetworzonego HTML zamiast wyzwalania prawdziwych żądań HTTP.

+0

Szukasz platformy testowej javascript lub internetowego narzędzia do wyodrębniania danych? Jeśli szukasz tylko narzędzia do zdrapywania piargów, możliwe jest zeskanowanie większości witryn bez wykonywania ich Javascript, nawet ciężkich AJAX. – chesles

+1

Pytanie dotyczy skrobaczki internetowej. Masz rację, często jest to możliwe, bez wykonywania Js, np. poprzez ręczne wysyłanie żądań REST. W przypadku Facebooka, zbieranie wersji mobilnej witryny jest całkiem możliwe przy użyciu tylko analizy HTTP i HTML. Ale interesuje mnie ogólne rozwiązanie, które rozumie Javascript i nie wymaga prawdziwej instancji przeglądarki. Wydaje się to być możliwe, jak pokazuje to JJ i zombie.Js, ale wydaje się, że jest to problem sztuczek. –

Odpowiedz

12

Dla celów ekstrakcji danych, uruchomienie "przeglądarki bezgłowej" i ręczne wyzwalanie zdarzeń javascript nie będzie najłatwiejsze. Chociaż nie jest to niemożliwe, istnieją prostsze sposoby na zrobienie tego.

Większość witryn, nawet ciężkich AJAX, może być zeskrobana bez wykonywania jednego wiersza kodu Javascript. W rzeczywistości jest to zwykle łatwiejsze niż próba odgadnięcia kodu Javascript witryny, który jest często zaciemniany, skracany i trudny do debugowania. Jeśli masz solidne zrozumienie protokołu HTTP, zrozumiesz, dlaczego: (prawie) wszystkie interakcje z serwerem są kodowane jako żądania HTTP, więc niezależnie od tego, czy są inicjowane przez JavaScript, czy przez kliknięcie łącza lub niestandardowego kodu w programie bota, nie ma różnicy do serwera. (Mówię prawie, ponieważ kiedy Flash lub aplety się angażują, nie wiadomo, jakie dane latają, mogą być specyficzne dla aplikacji, ale wszystko, co zrobimy w JavaScript, przejdzie przez HTTP.)

Z tego względu możliwe jest naśladować użytkownika na dowolnej stronie internetowej za pomocą niestandardowego oprogramowania. Najpierw musisz być w stanie zobaczyć surowe żądania HTTP wysyłane na serwer. Możesz użyć serwera proxy, aby rejestrować żądania wysłane przez prawdziwą przeglądarkę do docelowej witryny. Istnieje wiele narzędzi, których możesz użyć do tego: Charles lub Fiddler są poręczne, najbardziej dedykowane screen-scraper tools mają wbudowane podstawowe proxy, rozszerzenie Firebug dla przeglądarki Firefox i Chrome mają podobne narzędzia do przeglądania żądań AJAX ... masz pomysł .

Po wyświetleniu żądań HTTP, które powstały w wyniku określonej akcji na stronie internetowej, można łatwo napisać program naśladujący te żądania; po prostu wyślij te same żądania do serwera i potraktuje twój program jak przeglądarkę, w której wykonano określoną akcję.

Istnieją różne biblioteki dla różnych języków oferujących różne możliwości. W przypadku ruby ​​widziałem wiele osób korzystających z mechanize for ruby.

Jeśli jedynym celem jest ekstrakcja danych, prawie zawsze będziesz w stanie uzyskać to, czego potrzebujesz, naśladując w ten sposób żądania HTTP. Nie wymaga JavaScript.

Uwaga - Skoro wspomniałeś Facebooka, należy wspomnieć, że skrobanie Facebooka konkretnie może być wyjątkowo trudne (choć nie niemożliwe), ponieważ Facebook ma środki pozwalające na wykrycie zautomatyzowany dostęp (używają więcej niż tylko CAPTCHA); oni wyłączą konto, jeśli zobaczą podejrzane działania z niego wynikające. W końcu jest przeciwko ich terms of service (sekcja 3.2).

+1

Dziękuję za sformułowanie tej wyrafinowanej odpowiedzi na to pytanie. Już używam Firebug i Fiddler2 do monitorowania ruchu HTTP do iz serwerów sieciowych, co jednak nie jest zbyt użyteczne, jeśli używany jest trudny do odwrócenia temat komunikacji, jak to robi wiele serwisów społecznościowych. Ale nawet jeśli możliwe jest korzystanie z interfejsu niskiego poziomu do rozmowy z serwerem sieciowym i wydobywania informacji, będzie to wymagało ciągłego podkręcania skrobaka, co może być bardzo czasochłonne. Env.js (który mam najwyższy [_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __, ale mogę) działa tak, jak chcę), pokazuje, że jest możliwa realistyczna symulacja –

+0

To prawda, że ​​Facebook i inne witryny starają się maksymalnie utrudnić ich witrynom; wolą korzystać z ich interfejsów API, aby lepiej kontrolować dostęp do programu, a tym samym lepiej chronić prywatność swoich użytkowników. – chesles

+0

Nadal emulacja użytkownika surfującego za pomocą takiego narzędzia jak Selenium wydaje się działać bez problemów (z wyjątkiem powolności), nie napotkałem żadnych przeszkód poza szerokim wykorzystaniem dynamicznych treści. Nawet OAuth nie jest zabezpieczony przed automatycznym dostępem, uwierzytelnianie może być wykonywane bez żadnych problemów i nawet nie wymaga Javascriptu. –

Powiązane problemy