Skip to content

Work with results

An extraction exposes records through three views. Choose the one that matches the task:

  • result.records — start here when you want one page-wide list. It combines sections only when doing so is safe; if their schemas are incompatible, it raises an error rather than flattening unlike data.
  • result.collections — use a collection when the same entities appear in several places and you want one record per identity without losing the original placements.
  • result.structured_content — use physical sections when the page contains different kinds of records, or when document order and placement matter.
from analog import analog
result = analog("https://quotes.toscrape.com/js/")
print(result.records[:3])

If result.records cannot combine the page safely, read result.preview() and select result.collections, a section with result.section(label), or all sections of a kind with result.sections_by_kind(kind).

Every extraction is saved locally under a handle. Reopening a result does not fetch or extract the page again:

from analog import results, history, latest
again = results.open("<handle>")
newest = latest()
for meta in history():
print(meta.handle, meta.url)

Artifacts live in your per-user cache dir (~/.cache/analog/results; macOS ~/Library/Caches/analog/results; ANALOG_CACHE_DIR overrides) and store structured records and the page’s markdown, never raw HTML. The store is size-bounded (oldest-opened evicted first); analog history shows the disk footprint, and analog rm supports --older-than 30d, --url-contains, and --dry-run.

Terminal window
analog describe <handle> # per-field stats: coverage, cardinality, samples
analog distinct <handle> sector # value counts for one field
analog find <handle> "fintech" # grep across sections, navigation, and outline
analog diff <handleA> <handleB> # what changed between two saves
analog rename-fields <handle> text_2=title # your names, remembered per URL
analog reorder-fields <handle> price name # named fields first, remembered per URL

result.structured_content always preserves physical sections in document order. A collection adds a combined view over compatible sections without replacing them:

collection = result.collections[0]
print(collection.records) # one record per canonical identity
print(collection.placement_count) # every physical placement
print(collection.sections) # the source Sections, in page order

Repeated records are ordered by their first appearance. The collection selects one authored placement for each identity; values from different placements are never fused. conflicting_identities names repeated identities whose shared values disagree.

When one collection covers the whole result, result.records, CSV, YAML, and DataFrame export use it automatically. The physical sections remain available for provenance, section markdown, and page-structure questions.

Every result carries the page’s skeleton alongside its records. result.outline reports each significant region with its fate — extracted (pointing at its section), not extracted (with the reason), or page structure — so “not on the page” and “on the page, not extracted” are always distinguishable. result.navigation is the site’s own map: labeled link trees per nav region, collapsed mega-menu content included, all URLs absolute. find searches records, navigation, and outline labels alike, so “where is the pricing page?” is one grep.

Terminal window
analog export <handle> -f csv --fields name,price --where "price < 20" --sort price --limit 10

--where supports =, !=, ~ (contains), and numeric comparisons. Sorting and numeric filters are value-aware: a price field keeps its source display string ("from $5.41") but sorts and compares by the real number. In Python, section.numeric("price") exposes the parallel numbers, and result.to_dataframe() builds a pandas DataFrame with real float64 columns (pip install "analog-sdk[dataframe]").

Uniform across commands so scripts can branch on $? by category: 0 success, 1 command error, 2 usage, 3 auth, 4 backend unreachable, 5 fetch refused/failed (including robots.txt refusals), 6 extraction failed.