All skills
simota avatar

/trawl

@95ba0d9
by shingo imotasimota/agent-skills85 stars
15

Architecting crawl and scraping systems: distributed crawler topology, URL frontier, politeness, compliance. Architecture-only. Not for single-page scraping (Vector) or ETL pipelines (Stream).

Use this Skill: https://skilld.dev/gh/simota/agent-skills/trawl

This session only. Nothing lands on disk.

referencelink-graph.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Link Graph Design

Overview

The link graph captures the hyperlink structure discovered during crawling. It drives seed prioritization, important page discovery, and scope bounding.

  Crawled Page A
    ├── Link → Page B (anchor: "pricing")
    ├── Link → Page C (anchor: "about us")
    └── Link → External D (anchor: "partner site")
         │
         ▼
  Link Graph Storage
    ├── Forward Index: A → [B, C, D]
    ├── Reverse Index: B → [A, E, F]
    └── Anchor Text Index: B → ["pricing", "plans", "cost"]

Data Structures

Adjacency Representations

Structure Memory/1B edges Insert Lookup Best For
Adjacency list (HashMap) ~24 GB O(1) amortized O(degree) Small/Medium, dynamic updates
Compressed Sparse Row (CSR) ~8 GB O(N) rebuild O(1) offset Large/Web-scale, static analysis
Edge list (sorted) ~16 GB O(1) append O(log N) binary search Streaming ingest, batch processing
Graph DB (Neo4j) Disk-backed O(1) O(1) traversal Complex queries, relationship analysis

Selection Guide

Need complex graph queries (shortest path, community detection)?
  → Graph DB (Neo4j / JanusGraph)

Need fast batch PageRank computation?
  → CSR in memory or on disk (RocksDB-backed)

Need real-time link insertion during crawl?
  → Adjacency list (HashMap) or Edge list (append-only)

Scale > 10B edges?
  → Distributed: HBase edge table or Spark GraphX

Anchor Text Schema

Edge record:
{
  from_url:       string    # Canonical source URL
  to_url:         string    # Canonical target URL
  anchor_text:    string    # Link text content
  context_window: string    # ±50 chars around the anchor (for relevance scoring)
  link_type:      enum      # INTERNAL | EXTERNAL | NOFOLLOW | UGC | SPONSORED
  discovered_at:  timestamp # First discovery timestamp
  last_seen_at:   timestamp # Most recent crawl where this link was found
  position:       enum      # NAV | CONTENT | FOOTER | SIDEBAR
}

Storage estimate: ~200 bytes/edge average
1 billion edges ≈ 200 GB raw, ~80 GB compressed (Snappy/ZSTD)

Link Type Classification

Type rel attribute Follow Index Priority Impact
INTERNAL (none) Yes High — same-domain authority flow
EXTERNAL (none) Yes Medium — cross-domain authority
NOFOLLOW rel="nofollow" No Low — no authority transfer
UGC rel="ugc" No Low — user-generated, unreliable
SPONSORED rel="sponsored" No None — paid placement

PageRank-Variant Seed Prioritization

Standard PageRank

Parameters:
  Damping factor (d): 0.85 (standard)
  Convergence threshold (ε): 10^-6
  Max iterations: 100

Formula:
  PR(A) = (1-d)/N + d × Σ(PR(T)/C(T)) for all T linking to A
  where:
    N = total pages
    T = pages linking to A
    C(T) = outbound link count of T

Convergence: typically 40-60 iterations for 1M+ page graphs

Topic-Sensitive PageRank (for focused crawls)

Modification:
  Replace uniform teleportation (1-d)/N with biased teleportation:
  PR(A) = (1-d) × topic_weight(A) + d × Σ(PR(T)/C(T))

  topic_weight(A) = 1.0 if A matches target topic, 0.0 otherwise
  (normalized so Σ topic_weight = 1.0)

Use case: Domain-specific crawls where seed URLs define the topic.
Benefit: Pages relevant to the crawl topic get 3-5x higher priority.

Simplified Seed Scoring (when full PageRank is too expensive)

seed_score(URL) = w1 × in_link_count
               + w2 × domain_authority
               + w3 × sitemap_priority
               + w4 × (1 / hop_depth)

Recommended weights:
  w1 = 0.3 (in-link count, log-normalized)
  w2 = 0.3 (domain-level authority estimate)
  w3 = 0.2 (sitemap <priority> value, 0.0-1.0)
  w4 = 0.2 (inverse depth: root=1.0, depth-1=0.5, depth-2=0.33)

Advantage: O(1) per URL, no graph traversal needed.
Trade-off: Less accurate than PageRank but sufficient for frontier prioritization.

Scope Bounding

Hop Depth × Domain Affinity

scope_score(URL) = domain_affinity(URL) × depth_factor(URL)

domain_affinity:
  Same domain as seed:      1.0
  Same registered domain:   0.8  (e.g., blog.example.com for seed example.com)
  Linked domain (1 hop):    0.3
  Linked domain (2+ hops):  0.1

depth_factor:
  depth_factor = max(0, 1.0 - (hop_depth / max_depth))
  where max_depth is configurable (default: 5)

Decision:
  scope_score ≥ 0.3 → include in frontier
  scope_score < 0.3 → discard (out of scope)

Domain Scope Strategies

Strategy Rule Best For
Same-domain only Only URLs matching seed domain(s) Focused site crawls
Same-registered-domain Include all subdomains Company-wide crawls
Follow-one-hop Follow external links one hop out Discovery crawls
Allowlist Only domains in explicit allowlist Compliance-restricted crawls
Denylist + open Follow all except denied domains Broad research crawls

Use Cases

Important Page Discovery

  • Run PageRank on the crawled link graph (Personalized PageRank for topic-focused crawls)
  • Pages with PR > mean + 2σ are "important"
  • Use as priority boost in re-crawl scheduling
  • External authority signals: Common Crawl Webgraph (latest release cc-main-2025-26-nov-dec-jan, 250.8M host nodes / 10.9B edges; domain-level 121.3M / 6.2B); Open PageRank (free decile rank); Majestic Trust Flow (commercial). Use as seed-priority feature when the crawled subgraph is too sparse for in-house PageRank.

Orphan Page Detection

  • Pages with in_link_count = 0 (no internal links pointing to them)
  • Common in large sites — pages exist but are unreachable from navigation
  • Flag for site owner or exclude from index

Domain Relationship Analysis

  • Aggregate edges by domain → domain-level graph
  • Identify link farms (domains with > 90% outbound links to a single target)
  • Detect content syndication networks (bidirectional high-volume linking)

Storage Backend Selection

Backend Edges Query Types Latency Best For
RocksDB < 1B Point lookup, range scan < 1ms Medium tier, single-node
Neo4j < 100M Traversal, path queries 1-10ms Complex graph analysis
HBase 1B+ Point lookup, scan 5-50ms Web-scale, distributed
Spark GraphX 1B+ Batch PageRank, analytics Minutes Offline analysis
DuckDB < 100M SQL analytics on edges < 1ms Ad-hoc analysis, prototyping

Source: SKILL.md on GitHub

2 warnings1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    The 'trawl' skill is a comprehensive architecture tool for designing web crawling and scraping systems. It provides deep technical guidance on crawler topology, URL frontier management, and legal compliance without generating any executable code. No security risks or malicious patterns were identified.

  • Socket1mo

    1 alert: gptSecurity

  • Snyk1mo

    Risk: MEDIUM · 1 issue

Signed by skilld at 95ba0d9. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated last month

README badge

README badge for simota/agent-skills/trawl