Web Scraping e LLM

Guida a Python Web Scraping ed Estrazione LLM (2026)

Risposta Rapida: Nel 2026, i moderni python web scraping projects dedicati ai modelli LLM richiedono una pipeline a due stadi: rendering headless asincrono (Playwright o Crawl4AI) combinato con la potatura algoritmica del rumore DOM (rimozione di SVG, script e menu). Per dati strutturati, gli schemi Pydantic con Instructor assicurano output JSON deterministici abbattendo i costi di token del 75-88%.


1. Introduzione: Il Web Scraping nell'era dei Frontier LLM e degli Agenti AI

Gli agenti AI autonomi e le pipeline RAG necessitano di informazioni web fresche e affidabili. Sebbene modelli di punta come Claude 3.7 Sonnet, DeepSeek V3/R1 e GPT-4o offrano finestre di contesto fino a 2 milioni di token, inviare codice HTML grezzo all'attenzione del modello è un grave spreco di risorse.

In passato, per scrape website python, lo standard prevedeva requests con BeautifulSoup o Scrapy. Oggi il web è dominato da Single Page Application (SPA) dinamiche realizzate in Next.js, React e Vue, difese da WAF avanzati come Cloudflare Turnstile, DataDome e Akamai.

L'obiettivo è mutato:

  • Scraping Tradizionale (2015–2023): Estrarre campi rigidi in database relazionali tramite selettori XPath/CSS.
  • Scraping per Agenti e LLM (2026): Rimuovere il rumore del DOM, preservare la struttura Markdown ed estrarre JSON con validazione rigorosa tramite schemi Pydantic.

2. Confronto Framework: BeautifulSoup vs Scrapy vs Playwright vs Crawl4AI

Parametro BeautifulSoup4 + Requests Scrapy (Twisted/AsyncIO) Raw Playwright (Async Python) Crawl4AI (v0.9.x+)
Caso d'uso Script veloci e HTML statico Crawling massivo e distribuito SPA dinamiche e interazioni JS complesse Agenti AI, RAG ed estrazione LLM
Esecuzione JS Nessuna Nessuna (richiede Scrapy-Playwright) Motore completo Chromium e WebKit Chromium ottimizzato per LLM
Throughput ~15-25 req/s per worker ~150-300 req/s per spider ~5-12 pag/s per 16GB RAM ~25-45 pag/s (riutilizzo contesti)
Uso Memoria Minimo (~40MB) Basso (~120MB) Alto (150-350MB per contesto) Moderato (~80-140MB per tab)
Output Markdown Richiede libreria esterna Pipeline personalizzata Integrazione manuale Markdown nativo ottimizzato per LLM
Pulizia DOM Filtro manuale Selettori manuali Script CDP manuali PruningContentFilter e BM25 nativi
Evasione Anti-Bot Debole (solo User-Agent) Proxy middleware Ottima (playwright-stealth) Stealth nativo ed emulazione TLS
Supporto Pydantic Nessuno ItemLoaders Nessuno Motore nativo di schemi Pydantic

3. Economia dell'Estrazione per LLM: Pulizia del DOM e Risparmio Token

L'HTML grezzo è composto per oltre l'85% da classi CSS, script di tracciamento e blocchi di navigazione.

Analisi dei costi su 50.000 pagine al giorno (GPT-4o a $2.50 / 1M token)

  • Token giornalieri HTML grezzo: 50.000 × 55.000 = 2,75 miliardi di token
  • Token giornalieri Markdown pulito: 50.000 × 4.200 = 210 milioni di token
  • Risparmio giornaliero: (2.750 - 210) × $2.50 = $6.350,00 / giorno
  • Risparmio mensile: $190.500,00 / mese

4. Implementazione Pratica: Async Playwright e Selectolax

# clean_scraper.py
import asyncio
from playwright.async_api import async_playwright
from selectolax.parser import HTMLParser
import markdownify

async def scrape_clean_markdown(url: str) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True, args=["--no-sandbox"])
        page = await browser.new_page()
        await page.goto(url, wait_until="networkidle", timeout=30000)
        raw_html = await page.content()
        await browser.close()

    parser = HTMLParser(raw_html)
    for tag in ["script", "style", "svg", "noscript", "header", "footer", "nav", "aside"]:
        for node in parser.css(tag):
            node.decompose()

    main = parser.css_first("main, article, #content") or parser.css_first("body")
    return markdownify.markdownify(main.html if main else parser.html, heading_style="ATX")

5. Estrazione con Crawl4AI

# crawl4ai_pipeline.py
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
from crawl4ai.content_filter_strategy import PruningContentFilter

async def run_crawl4ai(url: str) -> str:
    async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler:
        config = CrawlerRunConfig(
            cache_mode=CacheMode.BYPASS,
            content_filter=PruningContentFilter(threshold=0.48),
            wait_until="networkidle"
        )
        res = await crawler.arun(url=url, config=config)
        return res.markdown

6. Estrazione JSON Strutturata con Pydantic e Instructor

# pydantic_extractor.py
import os
from typing import List, Optional
from pydantic import BaseModel, Field
import instructor
from openai import OpenAI

class TechSpec(BaseModel):
    name: str = Field(description="Nome funzionalità")
    supported: bool = Field(description="Supporto nativo")

class ProductInfo(BaseModel):
    product_name: str
    price_usd: Optional[float] = None
    specs: List[TechSpec]

def extract_data(clean_md: str) -> ProductInfo:
    client = instructor.from_openai(OpenAI(api_key=os.environ["OPENAI_API_KEY"]))
    return client.chat.completions.create(
        model="gpt-4o-mini",
        response_model=ProductInfo,
        messages=[{"role": "user", "content": clean_md}],
        temperature=0.0
    )

7. Evasione WAF e Richieste Stealth con curl_cffi

# stealth_requester.py
from curl_cffi import requests

def fetch_stealth(url: str, proxy: str = None) -> str:
    proxies = {"http": proxy, "https": proxy} if proxy else None
    return requests.get(url, impersonate="chrome124", proxies=proxies, timeout=15).text

8. Costi Complessivi per 100.000 Pagine

Voce di Costo Playwright Grezzo Playwright + Selectolax Crawl4AI Async Firecrawl Cloud
Infrastruttura Server $48.00 $22.00 $16.00 $0.00
Proxy Residenziali $120.00 $32.00 $30.00 Incluso
Inferenza LLM (GPT-4o) $13.750.00 $1.050.00 $975.00 $825.00
Costo Totale $13.918.00 $1.104.00 $1.021.00 $1.024.00

9. Linee Guida Architetturali

  1. Architettura a livelli: Usare curl_cffi per HTML statico e Crawl4AI per SPA dinamiche.
  2. Pulizia DOM tassativa: Eliminare il codice superfluo per ottenere oltre l'80% di riduzione token.
  3. Validazione Pydantic: Adottare Instructor per garantire output JSON privi di allucinazioni.
  4. Disaccoppiamento: Separare crawling e inferenza tramite code asincrone.
← Tutti gli Articoli
0 / 4