Browser-back / scraper.py
Nrighton233j
Add yt-dlp video extraction, page scraper, and speed optimizations (session reuse, parallel related-links search, caching)
080713a
Raw
History Blame Contribute Delete
1.99 kB
"""
scraper.py — fast server-side page fetching + clean text extraction.
Speed choices:
- requests.Session() reused across calls (connection pooling, keep-alive)
- gzip/deflate accepted so responses transfer smaller
- trafilatura for extraction (C-accelerated under the hood, much faster
and cleaner than manual BeautifulSoup heuristics)
- short TTL in-memory cache so repeated fetches of the same URL (e.g.
from /related hitting the same page twice) don't re-fetch over the wire
"""
import time
import requests
import trafilatura
SESSION = requests.Session()
SESSION.headers.update({
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
),
"Accept-Encoding": "gzip, deflate",
})
_CACHE = {}
CACHE_TTL_SECONDS = 120
def _cache_get(url: str):
entry = _CACHE.get(url)
if not entry:
return None
value, expires_at = entry
if time.time() > expires_at:
_CACHE.pop(url, None)
return None
return value
def _cache_set(url: str, value):
_CACHE[url] = (value, time.time() + CACHE_TTL_SECONDS)
def fetch_page(url: str, timeout: int = 8):
"""
Fetches a URL and returns clean extracted content:
{ title, text, excerpt, url }
Returns {"error": ...} on failure.
"""
cached = _cache_get(url)
if cached:
return cached
try:
resp = SESSION.get(url, timeout=timeout)
resp.raise_for_status()
except requests.RequestException as e:
return {"error": f"fetch failed: {e}"}
html = resp.text
text = trafilatura.extract(html, include_comments=False, include_tables=False) or ""
metadata = trafilatura.extract_metadata(html)
title = (metadata.title if metadata else "") or ""
result = {
"url": url,
"title": title,
"text": text.strip(),
"excerpt": text.strip()[:300],
}
_cache_set(url, result)
return result