Cache postcodes
This commit is contained in:
parent
f59d01227b
commit
8e4c56bb0d
7 changed files with 502 additions and 141 deletions
|
|
@ -29,6 +29,7 @@ from urllib.parse import parse_qsl, urlencode, urljoin, urlparse, urlunparse
|
|||
|
||||
import httpx
|
||||
|
||||
import shutdown
|
||||
from constants import (
|
||||
DATA_DIR,
|
||||
DELAY_BETWEEN_PAGES,
|
||||
|
|
@ -973,7 +974,7 @@ def _paginate(
|
|||
listing["_detail"] = fetch_detail(url)
|
||||
if not cached:
|
||||
detail_state["fetched"] += 1
|
||||
time.sleep(DELAY_BETWEEN_PAGES)
|
||||
shutdown.sleep(DELAY_BETWEEN_PAGES)
|
||||
|
||||
all_listings = _extract_listings(page)
|
||||
for listing in all_listings:
|
||||
|
|
@ -988,13 +989,15 @@ def _paginate(
|
|||
page_num = 2
|
||||
|
||||
while True:
|
||||
if shutdown.stop_requested():
|
||||
break
|
||||
next_url = _find_next_page_url(page)
|
||||
if not next_url:
|
||||
if total_results > 0 and len(all_listings) >= total_results:
|
||||
break
|
||||
next_url = _url_with_page(page.url, page_num)
|
||||
|
||||
time.sleep(DELAY_BETWEEN_PAGES)
|
||||
shutdown.sleep(DELAY_BETWEEN_PAGES)
|
||||
|
||||
try:
|
||||
page.goto(next_url, wait_until="domcontentloaded", timeout=30000)
|
||||
|
|
@ -1119,9 +1122,23 @@ def _extract_outcode(text: str) -> str | None:
|
|||
|
||||
# listingId -> parsed detail dict (or None). Failures are cached too, so a
|
||||
# broken listing is not re-fetched within a run (the same listing reappears
|
||||
# across overlapping outcode searches).
|
||||
# across overlapping outcode searches). Seeded from / dumped to a persistent
|
||||
# on-disk cache by the orchestrator (see postcode_cache.py) so a recurring
|
||||
# scrape only re-fetches newly-listed properties — the biggest saving for
|
||||
# Zoopla, whose detail fetch drives a real browser tab.
|
||||
_detail_cache: dict[str, dict | None] = {}
|
||||
|
||||
|
||||
def seed_detail_cache(mapping: dict) -> None:
|
||||
"""Pre-populate the in-memory detail cache from a persisted snapshot."""
|
||||
if mapping:
|
||||
_detail_cache.update(mapping)
|
||||
|
||||
|
||||
def detail_cache_snapshot() -> dict:
|
||||
"""Return a JSON-serialisable copy of the in-memory detail cache."""
|
||||
return dict(_detail_cache)
|
||||
|
||||
_LISTING_ID_RE = re.compile(r"/details/(\d+)/?")
|
||||
|
||||
# The property's own location is carried by a `"location":{...}` wrapper and a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue