v1 crawlers (crawl.js, src/main.rs) were developed using node v14.9.0 (npm v6.14.11) and rustc 1.52.1.
v2 crawlers (
crawl_v2.js,src/main_v2.rs) require Node >= 20.19 and Rust >= 1.85. See the v2 section below, and benchmarks comparing the two.
- Node.js
node crawl.js
- Rust
cargo run
- Node.js
SEED_LINK=https://medium.com/tag/web-scraping node crawl.js
- Rust
SEED_LINK=https://medium.com/tag/web-scraping cargo run
- Node.js
touch output.txt
SEED_LINK=https://devurls.com OUTPUT_FILE_PATH=./output.txt node crawl.js
- Rust
touch output.txt
SEED_LINK=https://devurls.com OUTPUT_FILE_PATH=./output.txt cargo run
- Node.js
touch output.txt
SEED_LINK=https://www.youtube.com OUTPUT_FILE_PATH=./output.txt node crawl.js > logs.txt
- Rust
touch output.txt
SEED_LINK=https://www.youtube.com OUTPUT_FILE_PATH=./output.txt cargo run > logs.txt
make clean
Modernized single-file rewrites living next to the originals:
crawl_v2.js— nativefetch+AbortSignal.timeout, cheerio HTML parsing,p-limitconcurrency pool,normalize-urlde-duplication,robots-parserpoliteness.src/main_v2.rs— asyncreqwestclient,scraperHTML parsing,urlrelative-link resolution,futuresbounded concurrency,std::sync::LazyLock/std::thread::available_parallelisminstead oflazy_static/num_cpus.
Both add a MAX_PAGES budget (default 100) so crawls terminate, per-request timeouts, asset-extension filtering, and a final crawl report. The output file is created automatically if missing.
- Node.js
npm install
node crawl_v2.js
- Rust
cargo run --bin web_crawler_v2
| Variable | Default | Notes |
|---|---|---|
SEED_LINK |
same defaults as v1 | starting URL |
OUTPUT_FILE_PATH |
./sites.txt |
created if missing |
MAX_PAGES |
100 |
crawl budget |
CONCURRENCY |
2× CPU parallelism | max in-flight requests |
REQUEST_TIMEOUT_MS / REQUEST_TIMEOUT_SECS |
10000 / 10 |
Node / Rust per-request timeout |
RESPECT_ROBOTS |
true |
Node only; set false to skip robots.txt checks |
DISABLE_LOGGING |
false |
set true for quiet mode |
Both suites run unit tests plus an end-to-end crawl against a local fixture HTTP server — no external network access needed.
- Node.js —
test.jstestscrawl_v2.jswith the built-innode:testrunner (requiresnpm installfirst)
npm install
npm test
(equivalent: node --test test.js)
- Rust —
tests/test.rstestssrc/main_v2.rs
cargo test
To run a single suite or test by name:
node --test --test-name-pattern="end to end" test.js
cargo test crawls_a_local_site_end_to_end
Both v2 crawlers were run concurrently for 5 minutes from the same seed (https://devurls.com) with identical settings (concurrency = 2× CPU parallelism, 10s timeouts), sampling CPU/RSS every 5 seconds. Full report: benchmark_results.txt.
Node.js v2 (crawl_v2.js) |
Rust v2 (web_crawler_v2, release) |
|
|---|---|---|
| Pages crawled | 4,019 (785/min) | 6,253 (1,222/min) |
| Request success rate | 79.9% | 73.7% |
| Distinct domains | 695 | 997 |
| CPU (avg / peak) | 51% / 196% | 10% / 53% |
| Memory RSS peak | 601 MB | 92 MB |
Rust crawled ~1.6× more pages at ~5× less CPU and ~6.5× less memory. Caveats: the two crawlers competed for the same network bandwidth, and the Node crawler honors robots.txt by default (487 pages skipped), which accounts for part of the gap.