Niedawno uczyłem się Pythona i wkładam rękę w tworzenie skrobaka internetowego. To nic nadzwyczajnego; jej jedynym celem jest pobranie danych z witryny bukmacherskiej i umieszczenie ich w programie Excel.
Większość problemów jest do rozwiązania i mam niezły bałagan. Jednak napotykam ogromną przeszkodę w jednym problemie. Jeśli witryna ładuje tabelę koni i podaje aktualne ceny zakładów, informacji tych nie ma w żadnym pliku źródłowym. Wskazówka jest taka, że te dane są czasami na żywo, a liczby są oczywiście aktualizowane z jakiegoś zdalnego serwera. HTML na moim komputerze ma po prostu dziurę, w której ich serwery przepychają wszystkie interesujące dane, których potrzebuję.
Teraz moje doświadczenie z dynamiczną zawartością sieciową jest niewielkie, więc mam problem ze zrozumieniem.
Myślę, że kluczem jest Java lub Javascript, często się to pojawia.
Skrobak to po prostu porównywarka kursów. Niektóre witryny mają interfejsy API, ale potrzebuję tego dla tych, które ich nie mają. Używam biblioteki scrapy w Pythonie 2.7
Przepraszam, jeśli to pytanie jest zbyt otwarte. Krótko mówiąc, moje pytanie brzmi: w jaki sposób można wykorzystać scrapy do zeskrobania tych dynamicznych danych, aby móc ich użyć? Więc mogę zeskrobać dane dotyczące kursów bukmacherskich w czasie rzeczywistym?
źródło
Firefox
rozszerzenia, takie jakhttpFox
lub,liveHttpHeaders
i załaduj stronę, która używa żądania AJAX. Scrapy nie identyfikuje automatycznie żądań Ajax, musisz ręcznie wyszukać odpowiedni adres URL Ajax, a następnie wysłać żądanie z tym żądaniem.Odpowiedzi:
Przeglądarki oparte na Webkit (takie jak Google Chrome czy Safari) mają wbudowane narzędzia programistyczne. W Chrome możesz go otworzyć
Menu->Tools->Developer Tools
.Network
Zakładka pozwala zobaczyć wszystkie informacje na temat każdego żądania i odpowiedzi:Na dole obrazka widać, że przefiltrowałem żądania do
XHR
- są to żądania wysyłane przez kod javascript.Wskazówka: dziennik jest czyszczony za każdym razem, gdy wczytujesz stronę, u dołu obrazu przycisk z czarną kropką zachowuje dziennik.
Po przeanalizowaniu żądań i odpowiedzi możesz zasymulować te żądania ze swojego robota internetowego i wyodrębnić cenne dane. W wielu przypadkach łatwiej będzie uzyskać dane niż parsowanie HTML, ponieważ dane te nie zawierają logiki prezentacji i są sformatowane tak, aby można było uzyskać do nich dostęp za pomocą kodu JavaScript.
Firefox ma podobne rozszerzenie, nazywa się firebug . Niektórzy twierdzą, że firebug jest jeszcze potężniejszy, ale podoba mi się prostota webkita.
źródło
Oto prosty przykład
scrapy
z żądaniem AJAX. Zobaczmy stronę rubin-kazan.ru .Wszystkie wiadomości są ładowane żądaniem AJAX. Moim celem jest pobranie tych wiadomości ze wszystkimi ich atrybutami (autor, data, ...):
Kiedy analizuję kod źródłowy strony, nie widzę wszystkich tych komunikatów, ponieważ strona korzysta z technologii AJAX. Ale mogę za pomocą Firebuga z Mozilla Firefox (lub równoważnego narzędzia w innych przeglądarkach) przeanalizować żądanie HTTP, które generuje komunikaty na stronie internetowej:
Nie ładuje ponownie całej strony, ale tylko części strony zawierające wiadomości. W tym celu klikam dowolną liczbę stron na dole:
I obserwuję żądanie HTTP odpowiedzialne za treść wiadomości:
Po zakończeniu analizuję nagłówki żądania (muszę zacytować, że ten adres URL wyodrębnię ze strony źródłowej z sekcji var, zobacz kod poniżej):
Oraz zawartość danych formularza żądania (metoda HTTP to „Post”):
Oraz treść odpowiedzi, czyli plik JSON:
Który zawiera wszystkie informacje, których szukam.
Od teraz całą tę wiedzę muszę wdrożyć w scrapy. W tym celu zdefiniujmy pająka:
W
parse
funkcji mam odpowiedź na pierwsze żądanie. WRubiGuessItem
mam plik JSON ze wszystkimi informacjami.źródło
re
modułu (wyrażenia regularne), wyszukuje ciąg znaków'url_list_gb_messages="(.*)"'
i izoluje zawartość nawiasów w zmiennej o tej samej nazwie. To jest fajne wprowadzenie: guru99.com/python-regular-expressions-complete-tutorial.htmlPodczas indeksowania często napotykamy problemy, w których treść renderowana na stronie jest generowana za pomocą JavaScript, przez co scrapy nie może jej zaindeksować (np. Żądania ajax, szaleństwo jQuery).
Jeśli jednak używasz Scrapy wraz z platformą do testowania sieci Selenium, jesteśmy w stanie zaindeksować wszystko, co jest wyświetlane w normalnej przeglądarce internetowej.
Kilka uwag:
Aby to działało, musisz mieć zainstalowaną wersję Selenium RC w języku Python i poprawnie skonfigurować Selenium. To jest tylko robot szablonów. Możesz stać się bardziej szalony i bardziej zaawansowany, ale chciałem tylko pokazać podstawową ideę. W obecnym stanie kodu będziesz wykonywać dwa żądania dla dowolnego adresu URL. Jedna prośba jest składana przez Scrapy, a druga przez Selenium. Jestem pewien, że istnieją sposoby obejścia tego problemu, abyś mógł po prostu zmusić Selenium do wykonania jednej i jedynej prośby, ale nie zawracałem sobie głowy implementacją tego, a wykonując dwa żądania, możesz również zaindeksować stronę za pomocą Scrapy.
Jest to dość potężne, ponieważ teraz masz cały wyrenderowany model DOM do przeszukania i nadal możesz używać wszystkich fajnych funkcji indeksowania w Scrapy. Spowoduje to oczywiście wolniejsze indeksowanie, ale w zależności od tego, jak bardzo potrzebujesz renderowanego DOM, warto poczekać.
Źródła: http://snipplr.com/view/66998/
źródło
selenium=3.3.1
ipython=2.7.10
, błąd podczas importowania z selen selenfrom selenium import webdriver
albochromedriver
albo cokolwiek zdarzy ci się być używany. Dokumenty EDIT: Add Reference dokumentacji i zmienić mój straszny gramatyki!Innym rozwiązaniem byłoby zaimplementowanie modułu obsługi pobierania lub oprogramowania pośredniego modułu obsługi pobierania. (zobacz dokumentację scrapy, aby uzyskać więcej informacji o oprogramowaniu pośredniczącym do pobierania) Poniżej znajduje się przykładowa klasa używająca selenu z bezgłowym sterownikiem sieciowym phantomjs:
1) Zdefiniuj klasę w
middlewares.py
skrypcie.2) Dodaj
JsDownload()
klasę do zmiennejDOWNLOADER_MIDDLEWARE
wsettings.py
:3) Zintegruj
HTMLResponse
wnętrzeyour_spider.py
. Dekodowanie treści odpowiedzi zapewni pożądane wyjście.Opcjonalny dodatek:
Chciałem mieć możliwość informowania różnych robotów pośredniczących, którego oprogramowania pośredniczącego użyć, więc zaimplementowałem ten wrapper:
aby owijarka działała, wszystkie pająki muszą mieć co najmniej:
aby dołączyć oprogramowanie pośredniczące:
Zaleta:
Główną zaletą implementacji w ten sposób, a nie w pająku, jest to, że kończy się tylko jedno żądanie. Na przykład w rozwiązaniu AT: program obsługi pobierania przetwarza żądanie, a następnie przekazuje odpowiedź pająkowi. Następnie pająk wysyła zupełnie nowe żądanie w swojej funkcji parse_page - to dwa żądania dotyczące tej samej treści.
źródło
process_requests
,if spider.name in ['spider1', 'spider2']
zamiast dekoratoraUżywałem niestandardowego oprogramowania pośredniczącego do pobierania, ale nie byłem z niego zadowolony, ponieważ nie udało mi się zmusić pamięci podręcznej do pracy z nim.
Lepszym podejściem było zaimplementowanie niestandardowego modułu obsługi pobierania.
Jest przykładem pracy tutaj . To wygląda tak:
Załóżmy, że twój skrobak nazywa się „skrobakiem”. Jeśli umieścisz wspomniany kod w pliku o nazwie handlers.py w katalogu głównym folderu "scraper", możesz dodać do swojego settings.py:
I voilà, JS przeanalizował DOM, z pamięcią podręczną scrapy, ponownymi próbami itp.
źródło
Zastanawiam się, dlaczego nikt nie opublikował rozwiązania wykorzystującego tylko Scrapy.
Przeczytaj wpis na blogu zespołu Scrapy SCRAPING INFINITE SCROLLING PAGES . Przykładowa skrawka http://spidyquotes.herokuapp.com/scroll strona internetowa, która używa nieskończonego przewijania.
Chodzi o to, aby użyć narzędzi deweloperskich swojej przeglądarki i zwrócić uwagę na żądania AJAX, a następnie na podstawie tych informacji utworzyć żądania dla Scrapy .
źródło
tak, Scrapy może usuwać dynamiczne strony internetowe, które są renderowane za pomocą javaScript.
Istnieją dwa podejścia do usuwania tego rodzaju witryn internetowych.
Pierwszy,
można użyć
splash
do renderowania kodu JavaScript, a następnie przeanalizować renderowany kod HTML. dokument i projekt można znaleźć tutaj Scrapy splash, gitDruga,
Jak wszyscy twierdzą, monitorując
network calls
, tak, możesz znaleźć wywołanie interfejsu API, które pobiera dane i udaje, że wywołanie w twoim pająku scrapy może pomóc ci uzyskać pożądane dane.źródło
Obsługuję żądanie Ajax za pomocą Selenium i sterownika internetowego Firefox. Nie jest tak szybki, jeśli potrzebujesz robota jako demona, ale znacznie lepszy niż jakiekolwiek rozwiązanie ręczne. Napisałem krótki samouczek tutaj jako odniesienie
źródło