

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Coroutines and Context Managers
incomplete
2: Concurrency
incomplete
3: Max Pages
incomplete
This lesson's interactive features are locked, please to keep using them
Your web crawler works – but it's crawling pages one at a time. It would take us a really long time to crawl a large website. Let's make it faster using coroutines. This is another long step, but don't get discouraged!
base_url (the starting URL)base_domain (the domain name)page_data (our dictionary of page data, keyed by normalized URL)visited (a set of normalized URLs already scheduled for crawling)lock (an asyncio.Lock to safely update page_data)max_concurrency (to limit the number of requests allowed at once)semaphore (an asyncio.Semaphore - pass it the value of max_concurrency)session (an aiohttp.ClientSession for making HTTP requests)async def __aenter__(self):
self.session = aiohttp.ClientSession()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.session.close()
async def add_page_visit(self, normalized_url):
async with on the lock field to safely check and update visitedvisited, return Falsevisited and return True before fetching the pageaiohttp client you set in the session field along with async with to fetch the page.add_page_visit method. If it isn't a new page, return earlyasync with self.semaphore to limit the number of concurrent requestsextract_page_datapage_data dictionary using the normalized URL as the key (use the lock to do this safely)outgoing_links as the URLs to crawl nextasyncio.create_taskawait asyncio.gather(*tasks)AsyncCrawler in an async with blockcrawl() and returns the final page_data dictionaryget_html, call crawl_site_async(base_url) and await the resultspage_data.values() to get the page dictionariesif __name__ == "__main__" block to run your async main function using asyncio.run(main())add_page_visit method returns a boolean: to indicate if it's the first time we've seen the page.semaphore to cap simultaneous requests