Come raschiare pagine a scorrimento infinito usando Python

Come fare, Pitone, Scraping, Mar-06-20245 minuti di lettura

Nel mondo di oggi, tutti fanno uso delle nuove tecnologie. Con l'aiuto del web scraping è possibile accedere ai dati strutturati in modo automatizzato. Ad esempio, è possibile utilizzare il web scraping per: Lo scorrimento infinito, noto anche come endless scrolling, è una tecnica di web design che i siti web utilizzano spesso con AJAX o Javascript.

Indice dei contenuti

Nel mondo di oggi, tutti fanno uso delle nuove tecnologie. Con l'aiuto del web scraping è possibile accedere ai dati strutturati in modo automatizzato. Ad esempio, è possibile utilizzare il web scraping per:

  • Monitoraggio dei prezzi
  • Generazione di lead
  • Monitoraggio delle notizie
  • Ricerca di mercato
  • Intelligenza del prezzo

Lo scorrimento infinito, noto anche come endless scrolling, è una tecnica di web design che i siti web utilizzano spesso con AJAX o Javascript per caricare dinamicamente contenuti aggiuntivi quando l'utente scorre verso il fondo della pagina web. Questa tecnica ha guadagnato popolarità grazie al suo successo sui siti di social media. Ad esempio, lo scorrimento infinito in Twitter è prodotto attraverso il caricamento asincrono. Twitter effettua chiamate AJAX dopo il caricamento della pagina per aggiungere continuamente nuovi contenuti durante lo scorrimento. Sebbene lo scorrimento infinito abbia molti vantaggi, non è raccomandato per attività di ricerca orientate a obiettivi che richiedono di individuare contenuti particolari.

Cerchiamo innanzitutto di capire quali sono i vantaggi dello scraping di pagine a scorrimento infinito.

Perché è necessario eseguire lo scraping di pagine a scorrimento infinito?

Di seguito sono riportati alcuni dei motivi per effettuare lo scraping di pagine a scorrimento infinito.

  • Coinvolgimento degli utenti - Lo scorrimento infinito mantiene gli utenti impegnati su una pagina. Nei siti di social media come Twitter e Facebook ci sono tonnellate di contenuti generati dagli utenti da scorrere, quindi l'utente è costantemente impegnato. 
  • Meno clic - Lo scorrimento richiede meno azioni ed è più facile per gli utenti rispetto al clic.
  • Ideale per i dispositivi mobili - Lo scorrimento infinito è ottimo per i dispositivi mobili e i touch screen. Gli utenti possono scorrere verso il basso per generare nuovi contenuti invece di passare a nuove schede. 

Oltre ai vantaggi di cui sopra, lo scraping di pagine a scorrimento infinito presenta anche alcuni svantaggi:

  • Non è un'ottima soluzione per l'ottimizzazione dei motori di ricerca (SEO).
  • Per gli utenti con disabilità fisiche non è facile navigare tra le pagine a scorrimento infinito.
  • I siti web a scorrimento infinito possono avere un lungo tempo di caricamento che può dipendere dall'utente o dallo sviluppo.

Come raschiare pagine a scorrimento infinito usando Python

Vediamo come effettuare lo scraping di pagine a scorrimento infinito utilizzando Python con l'aiuto dei passaggi indicati di seguito.

Importazione di librerie

È necessario importare la libreria Selenium.

da selenium import webdriver
da selenium.webdriver.common.keys import Keys    
importare tempo

Configurazione di Selenium

È necessario scegliere il browser che si desidera utilizzare. Noi sceglieremo Chrome perché offre più opzioni di Firefox. 

def get_selenium():                          
  options = webdriver.ChromeOptions()
  options.add_argument('--ignore-certificate-errors')
  options.add_argument('--incognito')
  options.add_argument('headless')                       
   driver = webdriver.Chrome(chrome_options=opzioni)
  return (driver)

L'argomento headless menzionato in precedenza è piuttosto importante. Selenium non aprirà Chrome in una nuova finestra quando viene eseguito headless in Python. Tuttavia, se si riscontra un problema durante lo scraping, è possibile commentare l'opzione headless e vedere cosa succede in Chrome e cosa viene caricato sulla pagina.

Possiamo omettere i due flag: ignore-certificate-errors e incognito.

Se si incontra un captcha o un cookie banner che impedisce il caricamento della pagina, si può fare clic su OK e procedere normalmente alla pagina. Tuttavia, se il browser si chiude inaspettatamente, si può usare time.sleep() per mettere in pausa il codice e prendersi tutto il tempo necessario per il debug.

Correzione dello scorrimento infinito

Per risolvere il problema dello scorrimento infinito, è necessario esaminare la struttura HTML della pagina e seguire i passaggi indicati di seguito.

  • Si deve trovare l'ultimo elemento caricato nella pagina.
  • È necessario utilizzare Selenium per scorrere verso il basso fino a quell'elemento.
  • Per attendere che la pagina carichi altro contenuto, utilizzare time.sleep().
  • Scorrere nuovamente fino all'ultimo elemento caricato nella pagina.
  • È necessario ripetere lo stesso procedimento fino a raggiungere la fine della pagina.

Per una migliore comprensione, si può considerare l'esempio seguente.

selenium = get_selenium()              
selenium.get("your/url")   
last_elem = '';
mentre Vero:
   current_last_elem = "#my-div > ul > li:last-child"
   scroll = "document.querySelector(\'" + current_last_elem + "\').scrollIntoView();"
   selenium.execute_script(scroll)
   time.sleep(3)
  se (last_elem == current_elem)
     pausa
  altrimenti
      last_elem = current_elem

Nel codice precedente, abbiamo usato jQuery e Javascript all'interno di Python. 

Qui,

  • Abbiamo usato la funzione selenium.get() che aprirà la nostra pagina URL. Tuttavia, se si vuole aggiungere una parola chiave alla ricerca dell'URL, si può utilizzare la seguente riga di codice.
selenium.get("your/url.com/{0}".format(keyword))
  • Abbiamo inizializzato last_time a 0, memorizzando una stringa vuota.
  • Abbiamo usato un ciclo while in cui abbiamo usato CSS_selector o Xpath per ottenere il current_last_elem. Per ottenere il percorso, seguire i passaggi seguenti. Per selezionare l'elemento di cui si vuole ottenere il percorso, è necessario utilizzare gli strumenti di webdev. È possibile seguire questa guida per selezionare l'elemento nella struttura HTML della pagina e ottenere il percorso X in Chrome.
  • Aprire la pagina.
  • Per selezionare un elemento di cui si desidera il percorso, è necessario utilizzare gli strumenti di webdev. Si può seguire questa guida per selezionare l'elemento nella struttura HTML della pagina e ottenere il percorso X in Chrome.
  • Per scorrere la pagina fino all'elemento selezionato, abbiamo usato jQuery e scrollIntoView(). 
"document.querySelector(\'" + .. + "\").scrollIntoView();"

Il formato deve essere corretto, quindi è necessario prestare attenzione alle virgolette singole e doppie e ai caratteri di escape.

  • Eseguiamo lo script js utilizzando selenium.execute_script().
  • È necessario dare alla pagina un tempo sufficiente per il caricamento, in modo che possa trovare l'ultimo elemento. Pertanto, la funzione time.sleep() è importante perché sospende l'esecuzione per alcuni secondi. Se non si concede alla pagina il tempo necessario per caricarsi, lo scorrimento si interromperà e si otterrà un risultato non definito.
  • Controlliamo se viene trovato un nuovo ultimo elemento ogni volta che scorriamo verso il fondo della pagina. Se viene trovato, significa che non abbiamo ancora raggiunto la fine della pagina e dobbiamo continuare a scorrere. Se non viene trovato, significa che la pagina ha finito di scorrere verso il basso e possiamo uscire dal ciclo.

Risolvere i problemi più frequenti

Alcuni dei problemi che si verificano frequentemente durante lo scorrimento infinito sono i seguenti:

  • Ci vuole un po' di tempo per trovare il percorso X giusto per l'ultimo elemento. È necessario controllare le virgolette singole e doppie nello script js.
  • Se si ottiene undefined o lo stesso ultimo elemento ogni volta, è necessario aumentare la durata del tempo, cioè aumentare time.sleep(), poiché la pagina potrebbe non avere abbastanza tempo per caricarsi completamente. 
  • È possibile commentare l'opzione headless in get_selenium() se tutto è corretto, ma non funziona comunque.

Trigger js all'interno di Python

È possibile attivare uno script js da Python e ottenere un elenco come risultato. 

Ad esempio, possiamo usare il codice seguente per ottenere le fonti di tutte le immagini della pagina.

js_script = '''\    
var jslist = []  
document.querySelectorAll('img').forEach(i => jslist.push(i.src));
restituire jslist; 
 '''  
python_list = selenium.execute_script(js_script)

Nel codice sopra riportato,

  • Abbiamo creato un array vuoto chiamato jslist.
  • Abbiamo selezionato tutti i tag img della pagina.
  • Abbiamo usato forEach per spingere ogni img.src nel nostro array.
  • Abbiamo restituito la jslist.

Possiamo utilizzare lo stesso approccio per i link href:

  • Selezione di tutti i tag "a".
  • Spingendo ogni a.href nel nostro array.

Successivamente, possiamo eseguire lo script con selenium.execute_script(). Possiamo quindi immagazzinare il valore restituito da js in una variabile python, cioè python_list. 

Ecco come possiamo effettuare lo scraping di pagine a scorrimento infinito utilizzando Python.

Utilizzo di un proxy

Si sa che un proxy è un server di terze parti che funge da intermediario tra un client che richiede una risorsa e un server che la fornisce. Se si desidera utilizzare i proxy con Selenium e Python, è possibile utilizzare le seguenti righe di codice.

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s'% hostname +": "+port)
driver = webdriver.Chrome(chrome_options=chrome_options)

Per gestire lo scorrimento infinito, si può usare scroll-proxy, che supporta lo scorrimento programmatico delle viste scrollabili all'interno di una gerarchia di viste. Se si usa npm, si può installare scroll-proxy usando il comando seguente. Utilizzeremo js per dimostrare l'uso di scroll-proxy.

npm install scroll-proxy--save

Dopo aver installato scroll-proxy, è possibile istanziare un oggetto ScrollProxy utilizzando il codice seguente.

var myScroll = new ScrollProxy();

Si può notare che non è stato passato alcun parametro al costruttore di ScrollProxy, perché esso segnalerà le azioni per impostazione predefinita quando l'utente scorre la pagina.

Tuttavia, se si desidera ottenere aggiornamenti quando l'utente scorre all'interno di un elemento HTML specifico, è necessario passarlo nel costruttore.

var myDiv = document.querySelector('.scrollable');
var myDivScroll = new ScrollProxy(myDiv);

Perché usare i proxy per lo scraping a scorrimento infinito?

Di seguito sono riportati alcuni motivi per utilizzare i proxy durante lo scraping a scorrimento infinito.

  • Un captcha può causare il timeout della pagina e bloccare lo scraper. Se si verificano frequenti errori di timeout, è possibile controllare manualmente la pagina alla ricerca di un captcha. La maggior parte dei captcha viene attivata da misure di sicurezza, che possono essere evitate utilizzando proxy residenziali a rotazione insieme allo scraper.
  • Alcuni siti preferiscono filtrare le richieste di intestazione sospette sulla base dell'ipotesi o della probabilità che l'agente utente possa essere un bot. Per evitare di segnalare che l'utente è un bot, è possibile utilizzare dei proxy in grado di cambiare l'indirizzo IP e di evitare le bandiere rosse per l'utente (user-agent). 

Conclusione

Abbiamo detto che lo scorrimento infinito è preferibile quando l'utente non è alla ricerca di informazioni specifiche. I siti web di notizie e i feed dei social media che generano costantemente nuovi contenuti possono beneficiare dello scorrimento infinito. D'altro canto, le pagine aziendali e i siti di e-commerce non sono buoni candidati per lo scorrimento infinito, poiché gli utenti cercano informazioni specifiche. Inoltre, abbiamo discusso i passaggi necessari per lo scraping di pagine a scorrimento infinito utilizzando Selenium. Per gestire lo scorrimento infinito possiamo anche utilizzare i proxy residenziali a rotazione, che ci aiutano a evitare i captchas e a filtrare le richieste di intestazione sospette.

Spero che abbiate capito come effettuare lo scraping di pagine a scorrimento infinito utilizzando Python.