2012-07-12 11 views
8

Sto imparando a creare web scrapers e voglio rasentare TripAdvisor per un progetto personale, afferrando l'html usando urllib2. Tuttavia, sto riscontrando un problema in cui, utilizzando il codice riportato di seguito, l'html che ottengo non è corretto poiché la pagina sembra impiegare un secondo per reindirizzare (è possibile verificare ciò visitando l'URL), ma ottengo il codice dalla pagina che inizialmente appare brevemente.python urllib2 - attendi che la pagina finisca il caricamento/reindirizzamento prima dello scraping?

C'è qualche comportamento o parametro da impostare per assicurarsi che la pagina abbia completato il caricamento/reindirizzamento prima di ottenere il contenuto del sito web?

import urllib2 
from bs4 import BeautifulSoup 

bostonPage = urllib2.urlopen("http://www.tripadvisor.com/HACSearch?geo=34438#02,1342106684473,rad:S0,sponsors:ABEST_WESTERN,style:Szff_6") 
soup = BeautifulSoup(bostonPage) 
print soup.prettify() 

Edit: La risposta è completa, tuttavia, alla fine ciò che ha risolto il mio problema era questo: https://stackoverflow.com/a/3210737/1157283

+0

doesnt urllib generare un errore? c'è un redirectdirector per questi casi ... –

+0

@DonQuestion Nessun errore, ho appena ricevuto l'html dalla pagina che appare brevemente prima di essere reindirizzato. Voglio il codice HTML dalla pagina che appare alla fine. Cos'è questo redirectdirector, puoi elaborare? – Ken

+0

se usi urlopen, stai usando OpenerDirector.open() guarda i python-docs - sfortunatamente non è spiegato in 2-3 parole :-(: http://docs.python.org/library/urllib2.html? highlight = urllib2 # urllib2.OpenerDirector –

risposta

5

Inreresting il problema non è un redirect è che la pagina modifica il contenuto utilizzando JavaScript, ma urllib2 non hai JS motore di esso solo GETS dati, se javascript disabilitato sul browser si nota carica sostanzialmente lo stesso contenuto come quello che urllib2 rendimenti

import urllib2 
from BeautifulSoup import BeautifulSoup 

bostonPage = urllib2.urlopen("http://www.tripadvisor.com/HACSearch?geo=34438#02,1342106684473,rad:S0,sponsors:ABEST_WESTERN,style:Szff_6") 
soup = BeautifulSoup(bostonPage) 
open('test.html', 'w').write(soup.read()) 

test.html e disabilitare JS nel browser, più semplice contenuto di Firefox -> deselezionare abilita javascript, genera set di risultati identici.

Quindi cosa possiamo fare bene, per prima cosa dovrebbe verificare se il sito offre un'API, rottamazione tende ad essere cipiglio fino http://www.tripadvisor.com/help/what_type_of_tripadvisor_content_is_available

Travel/Hotel API's? sembra che potrebbe, anche se con alcune limitazioni.

Ma se abbiamo ancora bisogno di grattarlo, con JS, allora possiamo usare seleniumhttp://seleniumhq.org/ principalmente usato per i test, ma è facile e ha documenti abbastanza buoni.

Ho trovato anche questo Scraping websites with Javascript enabled? e questo http://grep.codeconsult.ch/2007/02/24/crowbar-scrape-javascript-generated-pages-via-gecko-and-rest/

speranza che aiuta.

Come nota a margine:

>>> import urllib2 
>>> from bs4 import BeautifulSoup 
>>> 
>>> bostonPage = urllib2.urlopen("http://www.tripadvisor.com/HACSearch?geo=34438#02,1342106684473,rad:S0,sponsors:ABEST_WESTERN,style:Szff_6") 
>>> value = bostonPage.read() 
>>> soup = BeautifulSoup(value) 
>>> open('test.html', 'w').write(value) 
+0

Grazie per la risposta. Vorrei provare a reiterare un po 'di ciò: così quando fai clic sulle diverse categorie come "Lusso" o "Famiglie", le modifiche che vedi nella pagina sono generate solo attraverso javascript? (cioè il codice per la pagina non cambia mai?) E quello che devo fare è trovare uno strumento che esegua il JS e quindi restituisca quel contenuto? Qual è il modo più semplice/il migliore da quello che hai consigliato? non appropriato per quello che sto cercando di fare in questo caso. Il selenio – Ken

+0

potrebbe essere il modo migliore per farlo, utilizza il browser effettivo anche se completamente automatizzato ma come tale ha bisogno di un browser installato con almeno un frame-buffer virtuale o ambiente desktop, poiché chiamerà uno su ... –