r/LocalLLaMA 2026 has regular threads on pairing local uncensored models (Dolphin, Wizard, Nous) with a cloud-hosted scraping backend. The split is deliberate: the LLM runs locally for privacy and flexibility, Scavio handles the hard scraping infrastructure. This tutorial builds that architecture. Scavio has no extract or crawl endpoint - it returns structured search data (SERP rows, Reddit post bodies, YouTube transcripts), not arbitrary page HTML or markdown. This tutorial uses what the API really returns for a URL: the Google result row, with its title, link and snippet. Fetch the page yourself when you genuinely need the full body.
Prerequisites
- Ollama or llama.cpp
- A local uncensored model (dolphin-mixtral, nous-hermes)
- A Scavio API key
- Python 3.10+
Walkthrough
Step 1: Run the local LLM
Ollama makes this one command.
ollama run dolphin-mixtralStep 2: Call Scavio for the scraping layer
Scavio handles the network/anti-bot side.
import requests, os
# Scavio returns structured search data, not page bodies: there is no extract
# or crawl endpoint. What you can get for a URL is the Google result row it
# already has - title, link and snippet. Fetch the page yourself when you need
# the full body.
def scavio_page_row(url, headers):
target = url.split("://")[-1].rstrip("/")
r = requests.post("https://api.scavio.dev/api/v2/google", headers=headers,
json={"query": "site:" + target}, timeout=30)
r.raise_for_status()
rows = r.json().get("organic_results", [])
return rows[0] if rows else {"title": "", "link": url, "snippet": ""}
API_KEY = os.environ['SCAVIO_API_KEY']
def fetch(url):
r = scavio_page_row(url, {'Authorization': f'Bearer {API_KEY}'})
return r.get('snippet', '')Step 3: Let the local LLM do extraction
No content filters on the extraction prompt.
import requests
def extract_with_local(html, instruction):
r = requests.post('http://localhost:11434/api/generate',
json={'model': 'dolphin-mixtral', 'prompt': f'{instruction}\n\nHTML:\n{html[:4000]}'})
return r.json()['response']Step 4: Wire the full pipeline
Fetch via Scavio, extract via local LLM.
def scrape(url, instruction):
html = fetch(url)
return extract_with_local(html, instruction)
print(scrape('https://target.com', 'Extract all product names and prices as JSON.'))Step 5: Validate output
Light schema check before saving.
import json
def validate(out):
try: json.loads(out); return True
except: return FalsePython Example
import os, requests
# Scavio returns structured search data, not page bodies: there is no extract
# or crawl endpoint. What you can get for a URL is the Google result row it
# already has - title, link and snippet. Fetch the page yourself when you need
# the full body.
def scavio_page_row(url, headers):
target = url.split("://")[-1].rstrip("/")
r = requests.post("https://api.scavio.dev/api/v2/google", headers=headers,
json={"query": "site:" + target}, timeout=30)
r.raise_for_status()
rows = r.json().get("organic_results", [])
return rows[0] if rows else {"title": "", "link": url, "snippet": ""}
API_KEY = os.environ['SCAVIO_API_KEY']
def scrape(url, instruction):
html = scavio_page_row(url, {'Authorization': f'Bearer {API_KEY}'}).get('snippet', '')
r = requests.post('http://localhost:11434/api/generate',
json={'model': 'dolphin-mixtral', 'prompt': f'{instruction}\n\n{html[:4000]}'})
return r.json().get('response', '')
print(scrape('https://example.com', 'List headings as JSON'))JavaScript Example
const API_KEY = process.env.SCAVIO_API_KEY;
export async function scrape(url, instruction) {
const s = await fetch('https://api.scavio.dev/api/v2/google', {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: url })
});
const html = (await s.json()).html || '';
const o = await fetch('http://localhost:11434/api/generate', {
method: 'POST',
body: JSON.stringify({ model: 'dolphin-mixtral', prompt: `${instruction}\n\n${html.slice(0, 4000)}` })
});
return (await o.json()).response;
}Expected Output
Fully local extraction logic with cloud-hosted scraping infrastructure. Per-page cost: 1 Scavio credit + local GPU time. Data never leaves local box except the URL.