This project is an asynchronous web scraper that crawls pages from a single domain, collects structured page data, and exports the results to a JSON report.
main()starts the program withasyncio.run(...)main()awaitscrawl_site_async(base_url)crawl_site_asynccreates anAsyncCrawlerand usesasync with- Entering
async withruns__aenter__, which opens the HTTP session crawl()starts crawling fromself.base_urlcrawl_page():- skips off-domain URLs
- normalizes the URL
- uses
add_page_visit()to avoid duplicate crawls - uses a semaphore to limit concurrent requests
- fetches HTML
- extracts page data
- saves it into shared
self.page_data - creates tasks for linked pages
- waits for them with
asyncio.gather(...)
- Leaving
async withruns__aexit__, which closes the session - The final
page_datadictionary is returned tomain() main()callswrite_json_report(page_data)to export the results
await: pauses until an async operation finishesasync with: manages setup and cleanup for async resourcesasyncio.Lock: protects shared state from concurrent accessasyncio.Semaphore: limits how many requests run at onceasyncio.create_task(): starts concurrent crawl tasksasyncio.gather(): waits for all created tasks to finish
The crawler stores shared crawl results in self.page_data.
- Keys: normalized URL strings
- Values: extracted page-data dictionaries
This allows the crawler to:
- avoid visiting the same page twice
- store results for all crawled pages in one place
Once crawling finishes, write_json_report(page_data, filename="report.json"):
- Converts
page_data.values()into a list, sorted by each page's"url" - Writes that list to a JSON file (
report.jsonby default) usingjson.dump(..., indent=2)
This produces a human-readable JSON array of page objects, making the crawl results easy to inspect or share.
The goal of the async design is to crawl pages faster than a sequential crawler while still safely managing shared data and limiting request concurrency. The JSON report step then turns that in-memory data into a durable, shareable artifact.
This project was originally built as part of the boot.dev curriculum.