Rendering JavaScript tramite proxy: soluzioni ai problemi di parsing
I siti web moderni utilizzano attivamente JavaScript per caricare i contenuti. Questo crea problemi durante l'automazione: le normali richieste HTTP restituiscono una pagina vuota invece dei dati. Ti spieghiamo come i server proxy aiutano a risolvere questo problema e quali strumenti utilizzare.
Qual è il problema del rendering JavaScript
Quando invii una normale richiesta GET a un sito web utilizzando requests o curl, il browser riceve un file HTML con contenitori vuoti. Il contenuto reale viene caricato successivamente tramite JavaScript:
- Caricamento dinamico dei dati — il contenuto arriva tramite richieste AJAX dopo il caricamento della pagina
- Single Page Applications (SPA) — React, Vue, Angular eseguono il rendering di tutto il contenuto sul client
- Protezione dai bot — i siti utilizzano intenzionalmente JS per verificare che sia un browser reale
- Caricamento pigro (lazy loading) — le immagini e il testo vengono caricati solo durante lo scorrimento
Risultato: il parser vede una pagina vuota, anche se nel browser tutto viene visualizzato normalmente. Questo è chiamato problema di rendering.
Perché i proxy aiutano
I proxy stessi non eseguono il rendering di JavaScript. Ma risolvono due problemi critici:
1. Bypass dei blocchi per IP
I siti bloccano le richieste automatiche per indirizzo IP. Se invii centinaia di richieste da un singolo IP, il server ti bannerà. Il proxy maschera il tuo vero IP, distribuendo le richieste attraverso diversi indirizzi. Questo consente al browser automatizzato (Selenium, Puppeteer) di funzionare senza blocchi.
2. Imitazione di un browser reale
Quando utilizzi un proxy insieme a strumenti come Puppeteer o Selenium, il sistema appare come un browser reale. Questo aiuta a superare i controlli anti-bot e ottenere HTML completamente renderizzato.
Punto chiave: proxy + browser automatizzato = rendering JavaScript completo senza blocchi.
Quali proxy utilizzare
Per il rendering JavaScript sono adatti diversi tipi di proxy. La scelta dipende dal compito:
| Tipo di proxy | Velocità | Costo | Quando utilizzare |
|---|---|---|---|
| Data center | Molto alta | Bassa | Test, parsing dei propri siti, volumi elevati |
| Residenziali | Media | Alta | Bypass dei sistemi anti-bot, siti protetti, monitoraggio dei concorrenti |
| Mobili | Media | Alta | Applicazioni mobili, parsing mobile, automazione SMM |
Per il rendering JavaScript si consiglia: inizia con i data center per i test, quindi passa ai proxy residenziali se il sito blocca le richieste automatiche.
Strumenti per il rendering JavaScript
Puppeteer
Browser headless basato su Chromium. Ideale per l'automazione e il parsing. Funziona con i proxy tramite il parametro di configurazione.
Selenium
Strumento universale per l'automazione web. Supporta diversi browser (Chrome, Firefox, Edge) e si integra facilmente con i proxy.
Playwright
Alternativa moderna a Puppeteer con supporto per Chromium, Firefox e WebKit. Una buona scelta per i test cross-browser.
Splash (Scrapy)
Servizio di rendering JavaScript leggero. Puoi distribuirlo localmente o utilizzare la versione cloud.
Esempio pratico con codice
Esempio 1: Puppeteer con proxy
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: [
'--proxy-server=http://proxy-server:port'
]
});
const page = await browser.newPage();
// Impostazione del proxy con autenticazione (se richiesta)
await page.authenticate({
username: 'user',
password: 'pass'
});
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
const content = await page.content();
console.log(content);
await browser.close();
})();
Cosa accade:
--proxy-server— specifica il server proxypage.authenticate()— passa le credenziali per il proxywaitUntil: 'networkidle2'— attende il caricamento completo di tutte le risorse
Esempio 2: Selenium con proxy su Python
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = "proxy-server:port"
proxy.ssl_proxy = "proxy-server:port"
options = webdriver.ChromeOptions()
options.add_argument('--start-maximized')
capabilities = webdriver.DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)
driver = webdriver.Chrome(
desired_capabilities=capabilities,
options=options
)
driver.get('https://example.com')
content = driver.page_source
print(content)
driver.quit()
Esempio 3: Gestione del contenuto dinamico
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Inizializzazione con proxy
driver = webdriver.Chrome()
driver.get('https://example.com')
# Attesa del caricamento dell'elemento (fino a 10 secondi)
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "dynamic-content"))
)
# Estrazione del testo dopo il rendering
data = element.text
print(data)
driver.quit()
Consiglio: utilizza WebDriverWait invece di time.sleep() — è più affidabile e veloce.
Migliori pratiche
1. Rotazione dei proxy
Non utilizzare lo stesso proxy per tutte le richieste. Alterna gli indirizzi IP per evitare il blocco:
import random
proxies = [
'http://proxy1:port',
'http://proxy2:port',
'http://proxy3:port'
]
selected_proxy = random.choice(proxies)
# Utilizza selected_proxy per ogni richiesta
2. User-Agent
Cambia lo User-Agent per apparire come diversi browser:
options = webdriver.ChromeOptions()
options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
3. Ritardi tra le richieste
Aggiungi ritardi casuali per imitare il comportamento umano:
import time
import random
time.sleep(random.uniform(2, 5)) # Ritardo di 2-5 secondi
4. Gestione degli errori
Cattura sempre le eccezioni e registra i problemi:
try:
driver.get(url)
content = driver.page_source
except Exception as e:
print(f'Errore: {e}')
# Passa a un altro proxy o riprova
5. Chiusura del browser
Chiudi sempre il browser dopo l'uso per liberare le risorse:
try:
# Il tuo codice
finally:
driver.quit() # Garantisce la chiusura anche in caso di errore
Conclusioni
Il rendering JavaScript non è solo una sfida tecnica, ma una necessità nel web moderno. Ecco cosa ricordare:
- Problema: i parser comuni non vedono il contenuto dinamico caricato tramite JavaScript
- Soluzione: browser automatizzato (Puppeteer, Selenium) + server proxy
- Scelta del proxy: data center per i test, residenziali per i siti protetti
- Migliori pratiche: rotazione IP, ritardi, gestione degli errori, User-Agent
La combinazione di un browser automatizzato e di un server proxy consente di raccogliere dati in modo affidabile anche dai siti più complessi. Quando scegli uno strumento, considera la scala del progetto: Puppeteer è adatto per i piccoli progetti, Selenium per i progetti più grandi o soluzioni specializzate.
Per il bypass affidabile dei sistemi anti-bot e il parsing su larga scala, si consiglia di utilizzare proxy residenziali — appaiono come utenti reali e aiutano a evitare i blocchi.