From 6f02bfe8405084a1893560981df54b6cef877d79 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Mon, 25 Nov 2024 16:59:21 +0100 Subject: [PATCH 01/14] feat: draft an intro to the framework lesson --- .../scraping_basics_python/12_framework.md | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 4845c025b..916273d9d 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -6,25 +6,34 @@ sidebar_position: 12 slug: /scraping-basics-python/framework --- -:::danger Work in progress +**In this lesson, we'll rework our application for watching prices so that it builds on top of a scraping framework. We'll use Crawlee to make the program simpler, faster, and more robust.** -This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. +--- -::: +Before rewriting our code, let's point out several caveats in our current solution: + +- **Hard to maintain:** All the data we need from the listing page is also available on the product page. By scraping both, we have to maintain selectors for two HTML documents. Instead, we could scrape links from the listing page and process all data on the product pages. +- **Slow:** The program runs sequentially, which is considerate toward the target website, but downloading even two product pages in parallel could improve speed by 200%. +- **No logging:** The scraper gives no sense of progress, making it tedious to use. Debugging issues becomes even more frustrating without proper logs. +- **Boilerplate code:** We implement tasks like downloading and parsing HTML or exporting to CSV with custom code that feels like [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code). We could replace it with standardized solutions. +- **Prone to anti-scraping:** If the target website implemented anti-scraping measures, a bare-bones program like ours would stop working. +- **Browser means rewrite:** We got lucky extracting variants. If the website didn't include a fallback, we might have had no choice but to spin up a browser instance and automate clicking on buttons. Such a change in the underlying technology would require a complete rewrite of our program. +- **No error handling:** The scraper stops if it encounters issues. It should allow for skipping problematic products with warnings or retrying downloads when the website returns temporary errors. + +In this lesson, we'll tackle all the above issues by using a scraping framework while keeping the code concise. - +::: From d6bfaad38ad202aae1355663c2a5dd3d8135223f Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 12:42:34 +0100 Subject: [PATCH 02/14] feat: add first crawlee example --- .../scraping_basics_python/12_framework.md | 90 ++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 916273d9d..49136d20c 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -26,12 +26,100 @@ In this lesson, we'll tackle all the above issues by using a scraping framework From the two main open-source options for Python, [Scrapy](https://scrapy.org/) and [Crawlee](https://crawlee.dev/python/), we chose the latter—not just because we're the company financing its development. -We genuinely believe beginners to scraping will like it more, since it lets you create a scraper with less code and less time spent reading docs. Scrapy's long history ensures it's battle-tested, but it also means its code relies on technologies that aren't really necessary today. Crawlee, on the other hand, builds on modern Python features like asyncio and type hints. +We genuinely believe beginners to scraping will like it more, since it allows to create a scraper with less code and less time spent reading docs. Scrapy's long history ensures it's battle-tested, but it also means its code relies on technologies that aren't really necessary today. Crawlee, on the other hand, builds on modern Python features like asyncio and type hints. ::: ## Installing Crawlee +When starting with the Crawlee framework, you first need to decide which approach to downloading and parsing you'll prefer. We want the one based on BeautifulSoup, hence we'll install the `crawlee` package with the `beautifulsoup` extra specified in brackets. The framework has a lot of dependencies of its own, so expect the installation to take a while. + +```text +$ pip install crawlee[beautifulsoup] +... +Successfully installed Jinja2-0.0.0 ... ... ... crawlee-0.0.0 ... ... ... +``` + +## Running Crawlee + +Now let's use the framework to create a new version of our scraper. In the same project directory where our `main.py` file lives, create a file `newmain.py`. This way we can keep peeking at the original implementation when we're working on the new one. The initial content will look like this: + +```py title="newmain.py" +import asyncio +from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler + +async def main(): + crawler = BeautifulSoupCrawler() + + @crawler.router.default_handler + async def handle_listing(context): + print(context.soup.title.text.strip()) + + await crawler.run(["https://warehouse-theme-metal.myshopify.com/collections/sales"]) + +if __name__ == '__main__': + asyncio.run(main()) +``` + +In the code we do the following: + +1. We perform imports and specify an asynchronous `main()` function. +1. Inside, we first create a crawler. The crawler objects control the scraping. This particular crawler is of the BeautifulSoup flavor. +1. In the middle, we give the crawler a nested asynchronous function `handle_listing()`. Using a Python decorator (that line starting with `@`) we tell it to treat it as a default handler. Handlers take care of processing HTTP responses. This one finds the title of the page in `soup` and prints its text without whitespace. +1. The function ends with running the crawler with the products listing URL. We await until the crawler does its work. +1. The last two lines ensure that if we run the file as a standalone program, Python's asynchronous machinery `asyncio` will run our `main()` function. + +Don't worry if it's a lot of things you've never seen before. For now it's not really important to know exactly how [asyncio](https://docs.python.org/3/library/asyncio.html) works, or what decorators do. Let's stick to the practical side and see what the program does if executed: + +```text +$ python newmain.py +[crawlee.beautifulsoup_crawler._beautifulsoup_crawler] INFO Current request statistics: +┌───────────────────────────────┬──────────┐ +│ requests_finished │ 0 │ +│ requests_failed │ 0 │ +│ retry_histogram │ [0] │ +│ request_avg_failed_duration │ None │ +│ request_avg_finished_duration │ None │ +│ requests_finished_per_minute │ 0 │ +│ requests_failed_per_minute │ 0 │ +│ request_total_duration │ 0.0 │ +│ requests_total │ 0 │ +│ crawler_runtime │ 0.010014 │ +└───────────────────────────────┴──────────┘ +[crawlee._autoscaling.autoscaled_pool] INFO current_concurrency = 0; desired_concurrency = 2; cpu = 0; mem = 0; event_loop = 0.0; client_info = 0.0 +Sales +[crawlee._autoscaling.autoscaled_pool] INFO Waiting for remaining tasks to finish +[crawlee.beautifulsoup_crawler._beautifulsoup_crawler] INFO Final request statistics: +┌───────────────────────────────┬──────────┐ +│ requests_finished │ 1 │ +│ requests_failed │ 0 │ +│ retry_histogram │ [1] │ +│ request_avg_failed_duration │ None │ +│ request_avg_finished_duration │ 0.308998 │ +│ requests_finished_per_minute │ 185 │ +│ requests_failed_per_minute │ 0 │ +│ request_total_duration │ 0.308998 │ +│ requests_total │ 1 │ +│ crawler_runtime │ 0.323721 │ +└───────────────────────────────┴──────────┘ +``` + +If our previous program didn't give us any sense of progress, Crawlee feeds us with perhaps too much information for our purposes. Between all the diagnostics, notice the line `Sales`. That's the page title! We managed to create a Crawlee scraper which downloads the product listing page, parses it with BeautifulSoup, extracts the title, and prints it. + +## Crawling product detail pages + + + + + + :::danger Work in progress This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. From a52c5b488b4594c676b2fc20ad6735151c2b36b1 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 13:28:18 +0100 Subject: [PATCH 03/14] style: improve English --- .../scraping_basics_python/12_framework.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 49136d20c..d4403ffa8 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -32,7 +32,7 @@ We genuinely believe beginners to scraping will like it more, since it allows to ## Installing Crawlee -When starting with the Crawlee framework, you first need to decide which approach to downloading and parsing you'll prefer. We want the one based on BeautifulSoup, hence we'll install the `crawlee` package with the `beautifulsoup` extra specified in brackets. The framework has a lot of dependencies of its own, so expect the installation to take a while. +When starting with the Crawlee framework, we first need to decide which approach to downloading and parsing we prefer. We want the one based on BeautifulSoup, so let's install the `crawlee` package with the `beautifulsoup` extra specified in brackets. The framework has a lot of dependencies, so expect the installation to take a while. ```text $ pip install crawlee[beautifulsoup] @@ -42,7 +42,7 @@ Successfully installed Jinja2-0.0.0 ... ... ... crawlee-0.0.0 ... ... ... ## Running Crawlee -Now let's use the framework to create a new version of our scraper. In the same project directory where our `main.py` file lives, create a file `newmain.py`. This way we can keep peeking at the original implementation when we're working on the new one. The initial content will look like this: +Now let's use the framework to create a new version of our scraper. In the same project directory where our `main.py` file lives, create a file `newmain.py`. This way, we can keep peeking at the original implementation while working on the new one. The initial content will look like this: ```py title="newmain.py" import asyncio @@ -61,15 +61,15 @@ if __name__ == '__main__': asyncio.run(main()) ``` -In the code we do the following: +In the code, we do the following: 1. We perform imports and specify an asynchronous `main()` function. 1. Inside, we first create a crawler. The crawler objects control the scraping. This particular crawler is of the BeautifulSoup flavor. -1. In the middle, we give the crawler a nested asynchronous function `handle_listing()`. Using a Python decorator (that line starting with `@`) we tell it to treat it as a default handler. Handlers take care of processing HTTP responses. This one finds the title of the page in `soup` and prints its text without whitespace. -1. The function ends with running the crawler with the products listing URL. We await until the crawler does its work. -1. The last two lines ensure that if we run the file as a standalone program, Python's asynchronous machinery `asyncio` will run our `main()` function. +1. In the middle, we give the crawler a nested asynchronous function `handle_listing()`. Using a Python decorator (that line starting with `@`), we tell it to treat it as a default handler. Handlers take care of processing HTTP responses. This one finds the title of the page in `soup` and prints its text without whitespace. +1. The function ends with running the crawler with the product listing URL. We await the crawler to finish its work. +1. The last two lines ensure that if we run the file as a standalone program, Python's asynchronous machinery will run our `main()` function. -Don't worry if it's a lot of things you've never seen before. For now it's not really important to know exactly how [asyncio](https://docs.python.org/3/library/asyncio.html) works, or what decorators do. Let's stick to the practical side and see what the program does if executed: +Don't worry if this involves a lot of things you've never seen before. For now, you don't need to know exactly how [`asyncio`](https://docs.python.org/3/library/asyncio.html) works or what decorators do. Let's stick to the practical side and see what the program does when executed: ```text $ python newmain.py @@ -104,7 +104,7 @@ Sales └───────────────────────────────┴──────────┘ ``` -If our previous program didn't give us any sense of progress, Crawlee feeds us with perhaps too much information for our purposes. Between all the diagnostics, notice the line `Sales`. That's the page title! We managed to create a Crawlee scraper which downloads the product listing page, parses it with BeautifulSoup, extracts the title, and prints it. +If our previous scraper didn't give us any sense of progress, Crawlee feeds us with perhaps too much information for the purposes of a small program. Among all the diagnostics, notice the line `Sales`. That's the page title! We managed to create a Crawlee scraper that downloads the product listing page, parses it with BeautifulSoup, extracts the title, and prints it. ## Crawling product detail pages From 8404d193071c39bc7594e490850392a868b8da5d Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 13:49:00 +0100 Subject: [PATCH 04/14] style: few improvements to the text --- .../scraping_basics_python/12_framework.md | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index d4403ffa8..86c3fb6ad 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -13,14 +13,14 @@ slug: /scraping-basics-python/framework Before rewriting our code, let's point out several caveats in our current solution: - **Hard to maintain:** All the data we need from the listing page is also available on the product page. By scraping both, we have to maintain selectors for two HTML documents. Instead, we could scrape links from the listing page and process all data on the product pages. -- **Slow:** The program runs sequentially, which is considerate toward the target website, but downloading even two product pages in parallel could improve speed by 200%. +- **Slow:** The program runs sequentially, which is generously considerate toward the target website, but extremely inefficient. - **No logging:** The scraper gives no sense of progress, making it tedious to use. Debugging issues becomes even more frustrating without proper logs. -- **Boilerplate code:** We implement tasks like downloading and parsing HTML or exporting to CSV with custom code that feels like [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code). We could replace it with standardized solutions. +- **Boilerplate code:** We implement downloading and parsing HTML, or exporting data to CSV, although we're not the first people to meet and solve these problems. - **Prone to anti-scraping:** If the target website implemented anti-scraping measures, a bare-bones program like ours would stop working. - **Browser means rewrite:** We got lucky extracting variants. If the website didn't include a fallback, we might have had no choice but to spin up a browser instance and automate clicking on buttons. Such a change in the underlying technology would require a complete rewrite of our program. - **No error handling:** The scraper stops if it encounters issues. It should allow for skipping problematic products with warnings or retrying downloads when the website returns temporary errors. -In this lesson, we'll tackle all the above issues by using a scraping framework while keeping the code concise. +In this lesson, we'll tackle all the above issues while keeping the code concise thanks to a scraping framework. :::info Why Crawlee and not Scrapy @@ -104,21 +104,13 @@ Sales └───────────────────────────────┴──────────┘ ``` -If our previous scraper didn't give us any sense of progress, Crawlee feeds us with perhaps too much information for the purposes of a small program. Among all the diagnostics, notice the line `Sales`. That's the page title! We managed to create a Crawlee scraper that downloads the product listing page, parses it with BeautifulSoup, extracts the title, and prints it. +If our previous scraper didn't give us any sense of progress, Crawlee feeds us with perhaps too much information for the purposes of a small program. Among all the logging, notice the line `Sales`. That's the page title! We managed to create a Crawlee scraper that downloads the product listing page, parses it with BeautifulSoup, extracts the title, and prints it. ## Crawling product detail pages +## Extracting data - - - +## Saving data :::danger Work in progress From 8cc8c213e1786100821902011355b900ace8eda2 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 16:29:42 +0100 Subject: [PATCH 05/14] feat: crawl product detail pages --- .../scraping_basics_python/12_framework.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 86c3fb6ad..e99230e16 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -108,6 +108,69 @@ If our previous scraper didn't give us any sense of progress, Crawlee feeds us w ## Crawling product detail pages +The code now features advanced Python concepts, so it's less accessible to beginners to programming, and the size of the program is about the same as if we worked without framework. The tradeoff of using a framework is that primitive scenarios may become unnecessarily complex, while complex scenarios may become surprisingly primitive. + +As we'll rewrite the rest of the program, the benefits of using Crawlee will become more apparent. For example, it takes a single line of code to extract and follow links to products. Three more lines, and we have parallel processing of all the product detail pages: + +```py +import asyncio +from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler + +async def main(): + crawler = BeautifulSoupCrawler() + + @crawler.router.default_handler + async def handle_listing(context): + # highlight-next-line + await context.enqueue_links(label="DETAIL", selector=".product-list a.product-item__title") + + # highlight-next-line + @crawler.router.handler("DETAIL") + # highlight-next-line + async def handle_detail(context): + # highlight-next-line + print(context.request.url) + + await crawler.run(["https://warehouse-theme-metal.myshopify.com/collections/sales"]) + +if __name__ == '__main__': + asyncio.run(main()) +``` + +First, it's necessary to inspect the page in browser DevTools to figure out the CSS selector which allows us to locate links to all the product detail pages. Then we can use the `enqueue_links()` method to find the links, and add them to the Crawlee's internal HTTP request queue. We tell the method to label all the requests as `DETAIL`. + +Below, we give the crawler another asynchronous function, `handle_detail()`. We again inform the crawler that this function is a handler using a decorator, but this time it's not a default one. This handler will only take care of HTTP requests labeled as `DETAIL`. For now, all it does is that it prints the request URL. + +If we run the code, we should see how Crawlee first downloads the listing page, and then makes parallel requests to each of the detail pages, printing their URLs on the way: + +```text +$ python newmain.py +[crawlee.beautifulsoup_crawler._beautifulsoup_crawler] INFO Current request statistics: +... +[crawlee._autoscaling.autoscaled_pool] INFO current_concurrency = 0; desired_concurrency = 2; cpu = 0; mem = 0; event_loop = 0.0; client_info = 0.0 +https://warehouse-theme-metal.myshopify.com/products/sony-xbr-65x950g-65-class-64-5-diag-bravia-4k-hdr-ultra-hd-tv +https://warehouse-theme-metal.myshopify.com/products/jbl-flip-4-waterproof-portable-bluetooth-speaker +https://warehouse-theme-metal.myshopify.com/products/sony-sacs9-10-inch-active-subwoofer +https://warehouse-theme-metal.myshopify.com/products/sony-ps-hx500-hi-res-usb-turntable +... +[crawlee._autoscaling.autoscaled_pool] INFO Waiting for remaining tasks to finish +[crawlee.beautifulsoup_crawler._beautifulsoup_crawler] INFO Final request statistics: +┌───────────────────────────────┬──────────┐ +│ requests_finished │ 25 │ +│ requests_failed │ 0 │ +│ retry_histogram │ [25] │ +│ request_avg_failed_duration │ None │ +│ request_avg_finished_duration │ 0.349434 │ +│ requests_finished_per_minute │ 318 │ +│ requests_failed_per_minute │ 0 │ +│ request_total_duration │ 8.735843 │ +│ requests_total │ 25 │ +│ crawler_runtime │ 4.713262 │ +└───────────────────────────────┴──────────┘ +``` + +In the final statistics you can see that we made 25 requests (1 listing page + 24 product pages) in less than 5 seconds. Your numbers can differ, but regardless it should be much faster than making the requests sequentially. + ## Extracting data ## Saving data From 9338b547f289f2dbab45d23941c91645ef8f4803 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 16:49:34 +0100 Subject: [PATCH 06/14] style: improve English and add one paragraph --- .../scraping_basics_python/12_framework.md | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index e99230e16..11b381dd6 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -108,9 +108,9 @@ If our previous scraper didn't give us any sense of progress, Crawlee feeds us w ## Crawling product detail pages -The code now features advanced Python concepts, so it's less accessible to beginners to programming, and the size of the program is about the same as if we worked without framework. The tradeoff of using a framework is that primitive scenarios may become unnecessarily complex, while complex scenarios may become surprisingly primitive. +The code now features advanced Python concepts, so it's less accessible to beginners, and the size of the program is about the same as if we worked without a framework. The tradeoff of using a framework is that primitive scenarios may become unnecessarily complex, while complex scenarios may become surprisingly primitive. -As we'll rewrite the rest of the program, the benefits of using Crawlee will become more apparent. For example, it takes a single line of code to extract and follow links to products. Three more lines, and we have parallel processing of all the product detail pages: +As we rewrite the rest of the program, the benefits of using Crawlee will become more apparent. For example, it takes a single line of code to extract and follow links to products. Three more lines, and we have parallel processing of all the product detail pages: ```py import asyncio @@ -137,16 +137,18 @@ if __name__ == '__main__': asyncio.run(main()) ``` -First, it's necessary to inspect the page in browser DevTools to figure out the CSS selector which allows us to locate links to all the product detail pages. Then we can use the `enqueue_links()` method to find the links, and add them to the Crawlee's internal HTTP request queue. We tell the method to label all the requests as `DETAIL`. +First, it's necessary to inspect the page in browser DevTools to figure out the CSS selector that allows us to locate links to all the product detail pages. Then we can use the `enqueue_links()` method to find the links and add them to Crawlee's internal HTTP request queue. We tell the method to label all the requests as `DETAIL`. -Below, we give the crawler another asynchronous function, `handle_detail()`. We again inform the crawler that this function is a handler using a decorator, but this time it's not a default one. This handler will only take care of HTTP requests labeled as `DETAIL`. For now, all it does is that it prints the request URL. +Below that, we give the crawler another asynchronous function, `handle_detail()`. We again inform the crawler that this function is a handler using a decorator, but this time it's not a default one. This handler will only take care of HTTP requests labeled as `DETAIL`. For now, all it does is print the request URL. -If we run the code, we should see how Crawlee first downloads the listing page, and then makes parallel requests to each of the detail pages, printing their URLs on the way: +If we run the code, we should see how Crawlee first downloads the listing page and then makes parallel requests to each of the detail pages, printing their URLs along the way: ```text $ python newmain.py [crawlee.beautifulsoup_crawler._beautifulsoup_crawler] INFO Current request statistics: +┌───────────────────────────────┬──────────┐ ... +└───────────────────────────────┴──────────┘ [crawlee._autoscaling.autoscaled_pool] INFO current_concurrency = 0; desired_concurrency = 2; cpu = 0; mem = 0; event_loop = 0.0; client_info = 0.0 https://warehouse-theme-metal.myshopify.com/products/sony-xbr-65x950g-65-class-64-5-diag-bravia-4k-hdr-ultra-hd-tv https://warehouse-theme-metal.myshopify.com/products/jbl-flip-4-waterproof-portable-bluetooth-speaker @@ -169,10 +171,18 @@ https://warehouse-theme-metal.myshopify.com/products/sony-ps-hx500-hi-res-usb-tu └───────────────────────────────┴──────────┘ ``` -In the final statistics you can see that we made 25 requests (1 listing page + 24 product pages) in less than 5 seconds. Your numbers can differ, but regardless it should be much faster than making the requests sequentially. +In the final statistics, you can see that we made 25 requests (1 listing page + 24 product pages) in less than 5 seconds. Your numbers might differ, but regardless, it should be much faster than making the requests sequentially. ## Extracting data +The BeautifulSoup crawler provides handlers with the `context.soup` attribute, where we can find the parsed HTML of the handled page. This is the same as the `soup` we had in our previous program. + +:::danger Work in progress + +This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. + +::: + ## Saving data :::danger Work in progress From 4e3bf4ada55c7590c8dab769ffeed41e29e5e5be Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 17:48:16 +0100 Subject: [PATCH 07/14] feat: section about extracting data --- .../scraping_basics_python/12_framework.md | 95 ++++++++++++++++++- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 11b381dd6..06c975171 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -175,13 +175,100 @@ In the final statistics, you can see that we made 25 requests (1 listing page + ## Extracting data -The BeautifulSoup crawler provides handlers with the `context.soup` attribute, where we can find the parsed HTML of the handled page. This is the same as the `soup` we had in our previous program. +The BeautifulSoup crawler provides handlers with the `context.soup` attribute, where we can find the parsed HTML of the handled page. This is the same as the `soup` we had in our previous program. Let's locate and extract the same data as before: -:::danger Work in progress +```py +@crawler.router.handler("DETAIL") +async def handle_detail(context): + item = { + "url": context.request.url, + "title": context.soup.select_one(".product-meta__title").text.strip(), + "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), + } + print(item) +``` -This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. +Now the price. We won't be inventing anything new here-let's add `Decimal` import and copy-paste code from our old scraper. -::: +The only change will be in the selector. In `main.py`, we were looking for `.price` inside a `product_soup` representing a product card. Now we're looking for `.price` inside the whole product detail page. It's safer to be more specific so that we won't match another price on the same page: + +```py +@crawler.router.handler("DETAIL") +async def handle_detail(context): + price_text = ( + context.soup + # highlight-next-line + .select_one(".product-form__info-content .price") + .contents[-1] + .strip() + .replace("$", "") + .replace(",", "") + ) + item = { + "url": context.request.url, + "title": context.soup.select_one(".product-meta__title").text.strip(), + "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), + "price": Decimal(price_text), + } + print(item) +``` + +Finally, variants. We can reuse the `parse_variant()` function as it is, and even the handler code will look similar to what we already had. The whole program will look like this: + +```py +import asyncio +from decimal import Decimal +from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler + +async def main(): + crawler = BeautifulSoupCrawler() + + @crawler.router.default_handler + async def handle_listing(context): + await context.enqueue_links(selector=".product-list a.product-item__title", label="DETAIL") + + @crawler.router.handler("DETAIL") + async def handle_detail(context): + price_text = ( + context.soup + .select_one(".product-form__info-content .price") + .contents[-1] + .strip() + .replace("$", "") + .replace(",", "") + ) + item = { + "url": context.request.url, + "title": context.soup.select_one(".product-meta__title").text.strip(), + "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), + "price": Decimal(price_text), + "variant_name": None, + } + if variants := context.soup.select(".product-form__option.no-js option"): + for variant in variants: + print(item | parse_variant(variant)) + else: + print(item) + + await crawler.run(["https://warehouse-theme-metal.myshopify.com/collections/sales"]) + +def parse_variant(variant): + text = variant.text.strip() + name, price_text = text.split(" - ") + price = Decimal( + price_text + .replace("$", "") + .replace(",", "") + ) + return {"variant_name": name, "price": price} + +if __name__ == '__main__': + asyncio.run(main()) +``` + +If you run this scraper, you should see the same data about the 24 products as before. Crawlee has saved us a lot of work with downloading, parsing, logging, and parallelization. The code is also easier to follow with the two handlers separated and labeled. + +Crawlee doesn't help much with locating and extracting the data-that code is almost identical with or without framework. That's because the detective work involved, and taking care of the extraction, are the main added value of custom-made scrapers. With Crawlee, you can focus on just that, and let the framework take care of the rest. ## Saving data From 1b319b57f41a339287e218269c4624003b26cfd9 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Tue, 26 Nov 2024 18:00:34 +0100 Subject: [PATCH 08/14] style: improve English, add paragraph --- .../scraping_basics_python/12_framework.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 06c975171..a9037f2c7 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -175,7 +175,7 @@ In the final statistics, you can see that we made 25 requests (1 listing page + ## Extracting data -The BeautifulSoup crawler provides handlers with the `context.soup` attribute, where we can find the parsed HTML of the handled page. This is the same as the `soup` we had in our previous program. Let's locate and extract the same data as before: +The BeautifulSoup crawler provides handlers with the `context.soup` attribute, which contains the parsed HTML of the handled page. This is the same `soup` object we used in our previous program. Let's locate and extract the same data as before: ```py @crawler.router.handler("DETAIL") @@ -188,9 +188,9 @@ async def handle_detail(context): print(item) ``` -Now the price. We won't be inventing anything new here-let's add `Decimal` import and copy-paste code from our old scraper. +Now for the price. We're not doing anything new here—just import `Decimal` and copy-paste the code from our old scraper. -The only change will be in the selector. In `main.py`, we were looking for `.price` inside a `product_soup` representing a product card. Now we're looking for `.price` inside the whole product detail page. It's safer to be more specific so that we won't match another price on the same page: +The only change will be in the selector. In `main.py`, we looked for `.price` within a `product_soup` object representing a product card. Now, we're looking for `.price` within the entire product detail page. It's better to be more specific so we don't accidentally match another price on the same page: ```py @crawler.router.handler("DETAIL") @@ -213,7 +213,7 @@ async def handle_detail(context): print(item) ``` -Finally, variants. We can reuse the `parse_variant()` function as it is, and even the handler code will look similar to what we already had. The whole program will look like this: +Finally, the variants. We can reuse the `parse_variant()` function as-is, and in the handler we'll again take inspiration from what we had in `main.py`. The full program will look like this: ```py import asyncio @@ -266,12 +266,14 @@ if __name__ == '__main__': asyncio.run(main()) ``` -If you run this scraper, you should see the same data about the 24 products as before. Crawlee has saved us a lot of work with downloading, parsing, logging, and parallelization. The code is also easier to follow with the two handlers separated and labeled. +If you run this scraper, you should get the same data for the 24 products as before. Crawlee has saved us a lot of effort by managing downloading, parsing, logging, and parallelization. The code is also cleaner, with two separate and labeled handlers. -Crawlee doesn't help much with locating and extracting the data-that code is almost identical with or without framework. That's because the detective work involved, and taking care of the extraction, are the main added value of custom-made scrapers. With Crawlee, you can focus on just that, and let the framework take care of the rest. +Crawlee doesn't do much to help with locating and extracting the data—that part of the code remains almost the same, framework or not. This is because the detective work of finding and extracting the right data is the core value of custom scrapers. With Crawlee, you can focus on just that while letting the framework take care of everything else. ## Saving data +When we're at _letting the framework take care of everything else_, let's take a look at what it can do about saving data. + :::danger Work in progress This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. From 6af60e11bce5d58d36fbc51ccb2116d4efd1c13b Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Wed, 27 Nov 2024 16:53:14 +0100 Subject: [PATCH 09/14] feat: continue with the framework lesson --- .../scraping_basics_python/12_framework.md | 172 +++++++++++++++--- .../images/dataset-item.png | Bin 0 -> 128079 bytes 2 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 sources/academy/webscraping/scraping_basics_python/images/dataset-item.png diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index a9037f2c7..78f147aaf 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -178,14 +178,17 @@ In the final statistics, you can see that we made 25 requests (1 listing page + The BeautifulSoup crawler provides handlers with the `context.soup` attribute, which contains the parsed HTML of the handled page. This is the same `soup` object we used in our previous program. Let's locate and extract the same data as before: ```py -@crawler.router.handler("DETAIL") -async def handle_detail(context): - item = { - "url": context.request.url, - "title": context.soup.select_one(".product-meta__title").text.strip(), - "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), - } - print(item) +async def main(): + ... + + @crawler.router.handler("DETAIL") + async def handle_detail(context): + item = { + "url": context.request.url, + "title": context.soup.select_one(".product-meta__title").text.strip(), + "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), + } + print(item) ``` Now for the price. We're not doing anything new here—just import `Decimal` and copy-paste the code from our old scraper. @@ -193,24 +196,27 @@ Now for the price. We're not doing anything new here—just import `Decimal` and The only change will be in the selector. In `main.py`, we looked for `.price` within a `product_soup` object representing a product card. Now, we're looking for `.price` within the entire product detail page. It's better to be more specific so we don't accidentally match another price on the same page: ```py -@crawler.router.handler("DETAIL") -async def handle_detail(context): - price_text = ( - context.soup - # highlight-next-line - .select_one(".product-form__info-content .price") - .contents[-1] - .strip() - .replace("$", "") - .replace(",", "") - ) - item = { - "url": context.request.url, - "title": context.soup.select_one(".product-meta__title").text.strip(), - "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), - "price": Decimal(price_text), - } - print(item) +async def main(): + ... + + @crawler.router.handler("DETAIL") + async def handle_detail(context): + price_text = ( + context.soup + # highlight-next-line + .select_one(".product-form__info-content .price") + .contents[-1] + .strip() + .replace("$", "") + .replace(",", "") + ) + item = { + "url": context.request.url, + "title": context.soup.select_one(".product-meta__title").text.strip(), + "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), + "price": Decimal(price_text), + } + print(item) ``` Finally, the variants. We can reuse the `parse_variant()` function as-is, and in the handler we'll again take inspiration from what we had in `main.py`. The full program will look like this: @@ -272,10 +278,116 @@ Crawlee doesn't do much to help with locating and extracting the data—that par ## Saving data -When we're at _letting the framework take care of everything else_, let's take a look at what it can do about saving data. +When we're at _letting the framework take care of everything else_, let's take a look at what it can do about saving data. As of now the product detail page handler prints each item as soon as the item is ready. Instead, we can push the item to Crawlee's default dataset: + +```py +async def main(): + ... + + @crawler.router.handler("DETAIL") + async def handle_detail(context): + price_text = ( + ... + ) + item = { + ... + } + if variants := context.soup.select(".product-form__option.no-js option"): + for variant in variants: + # highlight-next-line + await context.push_data(item | parse_variant(variant)) + else: + # highlight-next-line + await context.push_data(item) +``` + +That's it! If you run the program now, there should be a `storage` directory alonside the `newmain.py` file. Crawlee uses it to store its internal state. If you go to the `storage/datasets/default` subdirectory, you'll see over 30 JSON files, each representing a single item. -:::danger Work in progress +![Single dataset item](images/dataset-item.png) -This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. +We can also export all the items to a single file of our choice. We'll do it at the end of the `main()` function, after the crawler has finished scraping: -::: +```py +async def main(): + ... + + await crawler.run(["https://warehouse-theme-metal.myshopify.com/collections/sales"]) + # highlight-next-line + await crawler.export_data_json(path='dataset.json', ensure_ascii=False, indent=2) + # highlight-next-line + await crawler.export_data_csv(path='dataset.csv') +``` + +After running the scraper again, there should be two new files in your directory, `dataset.json` and `dataset.csv`, containing all the data. If you peek into the JSON file, it should have indentation. + +## Logging + +While Crawlee gives us statistics about HTTP requests and concurrency, we otherwise don't have much visibility into pages we're crawling or items we're saving. Let's add custom logging where we see fit given our use case: + +```py +import asyncio +from decimal import Decimal +from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler + +async def main(): + crawler = BeautifulSoupCrawler() + + @crawler.router.default_handler + async def handle_listing(context): + # highlight-next-line + context.log.info("Looking for product detail pages") + await context.enqueue_links(selector=".product-list a.product-item__title", label="DETAIL") + + @crawler.router.handler("DETAIL") + async def handle_detail(context): + # highlight-next-line + context.log.info(f"Product detail page: {context.request.url}") + price_text = ( + context.soup + .select_one(".product-form__info-content .price") + .contents[-1] + .strip() + .replace("$", "") + .replace(",", "") + ) + item = { + "url": context.request.url, + "title": context.soup.select_one(".product-meta__title").text.strip(), + "vendor": context.soup.select_one(".product-meta__vendor").text.strip(), + "price": Decimal(price_text), + "variant_name": None, + } + if variants := context.soup.select(".product-form__option.no-js option"): + for variant in variants: + # highlight-next-line + context.log.info("Saving a product variant") + await context.push_data(item | parse_variant(variant)) + else: + # highlight-next-line + context.log.info("Saving a product") + await context.push_data(item) + + await crawler.run(["https://warehouse-theme-metal.myshopify.com/collections/sales"]) + + # highlight-next-line + crawler.log.info("Exporting data") + await crawler.export_data_json(path='dataset.json', ensure_ascii=False, indent=2) + await crawler.export_data_csv(path='dataset.csv') + +def parse_variant(variant): + text = variant.text.strip() + name, price_text = text.split(" - ") + price = Decimal( + price_text + .replace("$", "") + .replace(",", "") + ) + return {"variant_name": name, "price": price} + +if __name__ == '__main__': + asyncio.run(main()) +``` + +Depending on what we find useful, we can add more or less information to the logs. The `context.log` or `crawler.log` objects are [standard Python loggers](https://docs.python.org/3/library/logging.html). + +Even after we added extensive logging, we've been able to shave off at least 20 lines of code in comparison with the code of the original program. Over this lesson we've added more and more features to match the functionality of our old scraper, but despite that, the new code still has clear structure and is readable. And we could focus on what's specific to the website we're scraping and the data we're interested in, while framework took care of the rest. diff --git a/sources/academy/webscraping/scraping_basics_python/images/dataset-item.png b/sources/academy/webscraping/scraping_basics_python/images/dataset-item.png new file mode 100644 index 0000000000000000000000000000000000000000..afd19b9f2b96b62435af49c9e485063e68cb40c7 GIT binary patch literal 128079 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⁡@|gzqb5wMvJfmWt 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 Date: Wed, 27 Nov 2024 17:18:43 +0100 Subject: [PATCH 10/14] style: various wording fixes and additions --- .../scraping_basics_python/12_framework.md | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 78f147aaf..2719871d4 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -6,6 +6,8 @@ sidebar_position: 12 slug: /scraping-basics-python/framework --- +import Exercises from './_exercises.mdx'; + **In this lesson, we'll rework our application for watching prices so that it builds on top of a scraping framework. We'll use Crawlee to make the program simpler, faster, and more robust.** --- @@ -106,11 +108,17 @@ Sales If our previous scraper didn't give us any sense of progress, Crawlee feeds us with perhaps too much information for the purposes of a small program. Among all the logging, notice the line `Sales`. That's the page title! We managed to create a Crawlee scraper that downloads the product listing page, parses it with BeautifulSoup, extracts the title, and prints it. +:::tip Asynchronous code and decorators + +You don't need to be an expert in asynchronous programming or decorators to finish this lesson, but you might find yourself curious for more details. If so, check out [Async IO in Python: A Complete Walkthrough](https://realpython.com/async-io-python/) and [Primer on Python Decorators](https://realpython.com/primer-on-python-decorators/). + +::: + ## Crawling product detail pages -The code now features advanced Python concepts, so it's less accessible to beginners, and the size of the program is about the same as if we worked without a framework. The tradeoff of using a framework is that primitive scenarios may become unnecessarily complex, while complex scenarios may become surprisingly primitive. +The code now features advanced Python concepts, so it's less accessible to beginners, and the size of the program is about the same as if we worked without a framework. The tradeoff of using a framework is that primitive scenarios may become unnecessarily complex, while complex scenarios may become surprisingly primitive. As we rewrite the rest of the program, the benefits of using Crawlee will become more apparent. -As we rewrite the rest of the program, the benefits of using Crawlee will become more apparent. For example, it takes a single line of code to extract and follow links to products. Three more lines, and we have parallel processing of all the product detail pages: +For example, it takes a single line of code to extract and follow links to products. Three more lines, and we have parallel processing of all the product detail pages: ```py import asyncio @@ -171,7 +179,7 @@ https://warehouse-theme-metal.myshopify.com/products/sony-ps-hx500-hi-res-usb-tu └───────────────────────────────┴──────────┘ ``` -In the final statistics, you can see that we made 25 requests (1 listing page + 24 product pages) in less than 5 seconds. Your numbers might differ, but regardless, it should be much faster than making the requests sequentially. +In the final stats, you can see that we made 25 requests (1 listing page + 24 product pages) in less than 5 seconds. Your numbers might differ, but regardless, it should be much faster than making the requests sequentially. ## Extracting data @@ -272,7 +280,7 @@ if __name__ == '__main__': asyncio.run(main()) ``` -If you run this scraper, you should get the same data for the 24 products as before. Crawlee has saved us a lot of effort by managing downloading, parsing, logging, and parallelization. The code is also cleaner, with two separate and labeled handlers. +If you run this scraper, you should get the same data for the 24 products as before. Crawlee has saved us a lot of effort by managing downloading, parsing, and parallelization. The code is also cleaner, with two separate and labeled handlers. Crawlee doesn't do much to help with locating and extracting the data—that part of the code remains almost the same, framework or not. This is because the detective work of finding and extracting the right data is the core value of custom scrapers. With Crawlee, you can focus on just that while letting the framework take care of everything else. @@ -322,7 +330,7 @@ After running the scraper again, there should be two new files in your directory ## Logging -While Crawlee gives us statistics about HTTP requests and concurrency, we otherwise don't have much visibility into pages we're crawling or items we're saving. Let's add custom logging where we see fit given our use case: +Crawlee gives us stats about HTTP requests and concurrency, but we don't get much visibility into the pages we're crawling or the items we're saving. Let's add some custom logging: ```py import asyncio @@ -388,6 +396,18 @@ if __name__ == '__main__': asyncio.run(main()) ``` -Depending on what we find useful, we can add more or less information to the logs. The `context.log` or `crawler.log` objects are [standard Python loggers](https://docs.python.org/3/library/logging.html). +Depending on what we find helpful, we can tweak the logs to include more or less detail. The `context.log` or `crawler.log` objects are just [standard Python loggers](https://docs.python.org/3/library/logging.html). + +Even with the extra logging we've added, we've managed to cut at least 20 lines of code compared to the original program. Throughout this lesson, we've been adding features to match the old scraper's functionality, but the new code is still clean and readable. Plus, we've been able to focus on what's unique to the website we're scraping and the data we care about, while the framework manages the rest. + +In the next lesson, we'll use a scraping platform to set up our application to run automatically every day. -Even after we added extensive logging, we've been able to shave off at least 20 lines of code in comparison with the code of the original program. Over this lesson we've added more and more features to match the functionality of our old scraper, but despite that, the new code still has clear structure and is readable. And we could focus on what's specific to the website we're scraping and the data we're interested in, while framework took care of the rest. +--- + + + +:::danger Work in progress + +This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. + +::: From bb5b4bd2df891fc14a6b8aa2ee6e49950bb1430a Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Wed, 27 Nov 2024 17:24:35 +0100 Subject: [PATCH 11/14] style: make linter happy --- .../webscraping/scraping_basics_python/12_framework.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 2719871d4..34dcdf521 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -65,11 +65,11 @@ if __name__ == '__main__': In the code, we do the following: -1. We perform imports and specify an asynchronous `main()` function. -1. Inside, we first create a crawler. The crawler objects control the scraping. This particular crawler is of the BeautifulSoup flavor. -1. In the middle, we give the crawler a nested asynchronous function `handle_listing()`. Using a Python decorator (that line starting with `@`), we tell it to treat it as a default handler. Handlers take care of processing HTTP responses. This one finds the title of the page in `soup` and prints its text without whitespace. -1. The function ends with running the crawler with the product listing URL. We await the crawler to finish its work. -1. The last two lines ensure that if we run the file as a standalone program, Python's asynchronous machinery will run our `main()` function. +1. We perform imports and specify an asynchronous `main()` function. +1. Inside, we first create a crawler. The crawler objects control the scraping. This particular crawler is of the BeautifulSoup flavor. +1. In the middle, we give the crawler a nested asynchronous function `handle_listing()`. Using a Python decorator (that line starting with `@`), we tell it to treat it as a default handler. Handlers take care of processing HTTP responses. This one finds the title of the page in `soup` and prints its text without whitespace. +1. The function ends with running the crawler with the product listing URL. We await the crawler to finish its work. +1. The last two lines ensure that if we run the file as a standalone program, Python's asynchronous machinery will run our `main()` function. Don't worry if this involves a lot of things you've never seen before. For now, you don't need to know exactly how [`asyncio`](https://docs.python.org/3/library/asyncio.html) works or what decorators do. Let's stick to the practical side and see what the program does when executed: From 75d559ecd821a8a8c7086b5afb1503c6c8f5d5fd Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Thu, 28 Nov 2024 12:04:52 +0100 Subject: [PATCH 12/14] feat: add exercise --- .../scraping_basics_python/12_framework.md | 88 ++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 34dcdf521..4cbfd7e60 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -406,8 +406,90 @@ In the next lesson, we'll use a scraping platform to set up our application to r -:::danger Work in progress +### Build a Crawlee scraper of F1 Academy drivers -This course is incomplete. As we work on adding new lessons, we would love to hear your feedback. You can comment right here under each page or [file a GitHub Issue](https://github.com/apify/apify-docs/issues) to discuss a problem. +Scrape information about all [F1 Academy](https://en.wikipedia.org/wiki/F1_Academy) drivers listed on the official [Drivers](https://www.f1academy.com/Racing-Series/Drivers) page. Each item you push to the Crawlee's default dataset should contain the following data: -::: +- URL of the driver's f1academy.com page +- Name +- Team +- Nationality +- Date of birth (as a `date()` object) +- Instagram URL + +If you export the dataset as a JSON, you should see something like this: + +```text +[ + { + "url": "https://www.f1academy.com/Racing-Series/Drivers/29/Emely-De-Heus", + "name": "Emely De Heus", + "team": "MP Motorsport" + "nationality": "Dutch", + "dob": "2003-02-10", + "instagram_url": "https://www.instagram.com/emely.de.heus/", + }, + { + "url": "https://www.f1academy.com/Racing-Series/Drivers/28/Hamda-Al-Qubaisi", + "name": "Hamda Al Qubaisi", + "team": "MP Motorsport" + "nationality": "Emirati", + "dob": "2002-08-08", + "instagram_url": "https://www.instagram.com/hamdaalqubaisi_official/", + }, + ... +] +``` + +Hints: + +- Use Python's native `datetime.strptime(text, "%d/%m/%Y").date()` to parse the `DD/MM/YYYY` date format. See [docs](https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime) to learn more. +- Use the attribute selector `a[href*='instagram']` to locate the Instagram URL. See [docs](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) to learn more. + +
+ Solution + + ```py + import asyncio + from datetime import datetime + + from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler + + async def main(): + crawler = BeautifulSoupCrawler() + + @crawler.router.default_handler + async def handle_listing(context): + await context.enqueue_links(selector=".teams-driver-item a", label="DRIVER") + + @crawler.router.handler("DRIVER") + async def handle_driver(context): + info = {} + for row in context.soup.select(".common-driver-info li"): + name = row.select_one("span").text.strip() + value = row.select_one("h4").text.strip() + info[name] = value + + detail = {} + for row in context.soup.select(".driver-detail--cta-group a"): + name = row.select_one("p").text.strip() + value = row.select_one("h2").text.strip() + detail[name] = value + + await context.push_data({ + "url": context.request.url, + "name": context.soup.select_one("h1").text.strip(), + "team": detail["Team"], + "nationality": info["Nationality"], + "dob": datetime.strptime(info["DOB"], "%d/%m/%Y").date(), + "instagram_url": context.soup.select_one(".common-social-share a[href*='instagram']").get("href"), + }) + + await crawler.run(["https://www.f1academy.com/Racing-Series/Drivers"]) + await crawler.export_data_json(path='dataset.json', ensure_ascii=False, indent=2) + + if __name__ == '__main__': + asyncio.run(main()) + ``` + +
From f947c034b99aa6fce01f8f877e881278b6cad08d Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Thu, 28 Nov 2024 17:17:13 +0100 Subject: [PATCH 13/14] feat: add exercise --- .../11_scraping_variants.md | 2 +- .../scraping_basics_python/12_framework.md | 99 ++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/11_scraping_variants.md b/sources/academy/webscraping/scraping_basics_python/11_scraping_variants.md index 677414b31..f2682f55f 100644 --- a/sources/academy/webscraping/scraping_basics_python/11_scraping_variants.md +++ b/sources/academy/webscraping/scraping_basics_python/11_scraping_variants.md @@ -325,7 +325,7 @@ For each job posting found, use [`pp()`](https://docs.python.org/3/library/pprin Your output should look something like this: -```text +```py {'title': 'Senior Full Stack Developer', 'company': 'Baserow', 'url': 'https://www.python.org/jobs/7705/', diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 4cbfd7e60..3bb9788f3 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -419,7 +419,8 @@ Scrape information about all [F1 Academy](https://en.wikipedia.org/wiki/F1_Acade If you export the dataset as a JSON, you should see something like this: -```text + +```json [ { "url": "https://www.f1academy.com/Racing-Series/Drivers/29/Emely-De-Heus", @@ -493,3 +494,99 @@ Hints: ``` + +### Use Crawlee to find rating of the most popular Netflix films + +The [Global Top 10](https://www.netflix.com/tudum/top10) page contains a table of the most currently popular Netflix films worldwide. Scrape the movie names, then search for each movie at the [IMDb](https://www.imdb.com/). Assume the first search result is correct and find out what's the film's rating. Each item you push to the Crawlee's default dataset should contain the following data: + +- URL of the film's imdb.com page +- Title +- Rating + +If you export the dataset as a JSON, you should see something like this: + + +```json +[ + { + "url": "https://www.imdb.com/title/tt32368345/?ref_=fn_tt_tt_1", + "title": "The Merry Gentlemen", + "rating": "5.0/10" + }, + { + "url": "https://www.imdb.com/title/tt32359447/?ref_=fn_tt_tt_1", + "title": "Hot Frosty", + "rating": "5.4/10" + }, + ... +] +``` + +For each name from the Global Top 10, you'll need to construct a `Request` object with IMDb search URL. Take the following code snippet as a hint on how to do it: + +```py +... +from urllib.parse import quote_plus + +async def main(): + ... + + @crawler.router.default_handler + async def handle_netflix_table(context): + requests = [] + for name_cell in context.soup.select(...): + name = name_cell.text.strip() + imdb_search_url = f"https://www.imdb.com/find/?q={quote_plus(name)}&s=tt&ttype=ft" + requests.append(Request.from_url(imdb_search_url, label="...")) + await context.add_requests(requests) + + ... +... +``` + +When following the first search result, you may find handy to know that `context.enqueue_links()` takes a `limit` keyword argument, where you can specify the max number of HTTP requests to enqueue. + +
+ Solution + + ```py + import asyncio + from urllib.parse import quote_plus + + from crawlee import Request + from crawlee.beautifulsoup_crawler import BeautifulSoupCrawler + + async def main(): + crawler = BeautifulSoupCrawler() + + @crawler.router.default_handler + async def handle_netflix_table(context): + requests = [] + for name_cell in context.soup.select(".list-tbl-global .tbl-cell-name"): + name = name_cell.text.strip() + imdb_search_url = f"https://www.imdb.com/find/?q={quote_plus(name)}&s=tt&ttype=ft" + requests.append(Request.from_url(imdb_search_url, label="IMDB_SEARCH")) + await context.add_requests(requests) + + @crawler.router.handler("IMDB_SEARCH") + async def handle_imdb_search(context): + await context.enqueue_links(selector=".find-result-item a", label="IMDB", limit=1) + + @crawler.router.handler("IMDB") + async def handle_imdb(context): + rating_selector = "[data-testid='hero-rating-bar__aggregate-rating__score']" + rating_text = context.soup.select_one(rating_selector).text.strip() + await context.push_data({ + "url": context.request.url, + "title": context.soup.select_one("h1").text.strip(), + "rating": rating_text, + }) + + await crawler.run(["https://www.netflix.com/tudum/top10"]) + await crawler.export_data_json(path='dataset.json', ensure_ascii=False, indent=2) + + if __name__ == '__main__': + asyncio.run(main()) + ``` + +
From ecc715bc2304f306fce6d0488de5a44442e26c82 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Thu, 28 Nov 2024 17:26:42 +0100 Subject: [PATCH 14/14] style: English --- .../scraping_basics_python/12_framework.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sources/academy/webscraping/scraping_basics_python/12_framework.md b/sources/academy/webscraping/scraping_basics_python/12_framework.md index 3bb9788f3..2950de678 100644 --- a/sources/academy/webscraping/scraping_basics_python/12_framework.md +++ b/sources/academy/webscraping/scraping_basics_python/12_framework.md @@ -408,7 +408,7 @@ In the next lesson, we'll use a scraping platform to set up our application to r ### Build a Crawlee scraper of F1 Academy drivers -Scrape information about all [F1 Academy](https://en.wikipedia.org/wiki/F1_Academy) drivers listed on the official [Drivers](https://www.f1academy.com/Racing-Series/Drivers) page. Each item you push to the Crawlee's default dataset should contain the following data: +Scrape information about all [F1 Academy](https://en.wikipedia.org/wiki/F1_Academy) drivers listed on the official [Drivers](https://www.f1academy.com/Racing-Series/Drivers) page. Each item you push to Crawlee's default dataset should include the following data: - URL of the driver's f1academy.com page - Name @@ -417,7 +417,7 @@ Scrape information about all [F1 Academy](https://en.wikipedia.org/wiki/F1_Acade - Date of birth (as a `date()` object) - Instagram URL -If you export the dataset as a JSON, you should see something like this: +If you export the dataset as JSON, it should look something like this: ```json @@ -444,8 +444,8 @@ If you export the dataset as a JSON, you should see something like this: Hints: -- Use Python's native `datetime.strptime(text, "%d/%m/%Y").date()` to parse the `DD/MM/YYYY` date format. See [docs](https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime) to learn more. -- Use the attribute selector `a[href*='instagram']` to locate the Instagram URL. See [docs](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) to learn more. +- Use Python's `datetime.strptime(text, "%d/%m/%Y").date()` to parse dates in the `DD/MM/YYYY` format. Check out the [docs](https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime) for more details. +- To locate the Instagram URL, use the attribute selector `a[href*='instagram']`. Learn more about attribute selectors in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
Solution @@ -495,15 +495,15 @@ Hints:
-### Use Crawlee to find rating of the most popular Netflix films +### Use Crawlee to find the ratings of the most popular Netflix films -The [Global Top 10](https://www.netflix.com/tudum/top10) page contains a table of the most currently popular Netflix films worldwide. Scrape the movie names, then search for each movie at the [IMDb](https://www.imdb.com/). Assume the first search result is correct and find out what's the film's rating. Each item you push to the Crawlee's default dataset should contain the following data: +The [Global Top 10](https://www.netflix.com/tudum/top10) page has a table listing the most popular Netflix films worldwide. Scrape the movie names from this page, then search for each movie on [IMDb](https://www.imdb.com/). Assume the first search result is correct and retrieve the film's rating. Each item you push to Crawlee's default dataset should include the following data: - URL of the film's imdb.com page - Title - Rating -If you export the dataset as a JSON, you should see something like this: +If you export the dataset as JSON, it should look something like this: ```json @@ -522,7 +522,7 @@ If you export the dataset as a JSON, you should see something like this: ] ``` -For each name from the Global Top 10, you'll need to construct a `Request` object with IMDb search URL. Take the following code snippet as a hint on how to do it: +To scrape IMDb data, you'll need to construct a `Request` object with the appropriate search URL for each movie title. The following code snippet gives you an idea of how to do this: ```py ... @@ -544,7 +544,7 @@ async def main(): ... ``` -When following the first search result, you may find handy to know that `context.enqueue_links()` takes a `limit` keyword argument, where you can specify the max number of HTTP requests to enqueue. +When navigating to the first search result, you might find it helpful to know that `context.enqueue_links()` accepts a `limit` keyword argument, letting you specify the max number of HTTP requests to enqueue.
Solution