פיתון היא שפה יפה לקודד. יש לה מערכת אקולוגית חבילה נהדרת, יש הרבה פחות רעש ממה שתמצא בשפות אחרות, וזה קל מאוד לשימוש.
פייתון משמש למספר דברים, החל מניתוח נתונים וכלה בתכנות שרתים. ואחד ממקרי השימוש המרתקים של פייתון הוא גירוד באינטרנט.
במאמר זה נסקור כיצד להשתמש בפייתון לגרידה באינטרנט. אנו נעבור גם דרך מדריך כיתתי מלא של הכיתה בהמשך.
הערה: אנו מגרדים דף אינטרנט אותו אני מארח, כדי שנוכל ללמוד לגרד עליו בבטחה. חברות רבות אינן מאפשרות גרידה באתרי האינטרנט שלהן, ולכן זו דרך טובה ללמוד. רק דאג לבדוק לפני שאתה מגרד.
מבוא לכיתת גירוד אתרים

אם אתה רוצה לקודד, אתה יכול להשתמש בכיתה המקודדת החינמית הזוהמורכב ממעבדות מרובות שיעזרו לך ללמוד גרידה באינטרנט. זה יהיה תרגיל מעשי למידה מעשי ב- codedamn, בדומה לאופן שבו אתה לומד ב- freeCodeCamp.
בכיתה זו תשתמש בדף זה לבדיקת גירוד באינטרנט: //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
כיתה זו מורכבת משבע מעבדות ותפתור מעבדה בכל חלק בפוסט בבלוג זה. אנו נשתמש ב- Python 3.8 + BeautifulSoup 4 לגרידה באינטרנט.
חלק 1: טעינת דפי אינטרנט עם 'בקשה'
זהו הקישור למעבדה זו.
requests
מודול זה מאפשר לך לשלוח בקשות HTTP באמצעות Python.
בקשת ה- HTTP מחזירה אובייקט תגובה עם כל נתוני התגובה (תוכן, קידוד, סטטוס וכו '). דוגמה אחת לקבלת ה- HTML של דף:
import requests res = requests.get('//codedamn.com') print(res.text) print(res.status_code)
דרישות מעבר:
- קבל את התוכן של כתובת האתר הבאה באמצעות
requests
המודול: //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/ - אחסן את תגובת הטקסט (כפי שמוצג לעיל) במשתנה שנקרא
txt
- אחסן את קוד המצב (כפי שמוצג לעיל) במשתנה שנקרא
status
- דפס
txt
וstatus
באמצעותprint
פונקציה
ברגע שאתה מבין מה קורה בקוד לעיל, די פשוט לעבור את המעבדה הזו. להלן פיתרון מעבדה זו:
import requests # Make a request to //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/ # Store the result in 'res' variable res = requests.get( '//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/') txt = res.text status = res.status_code print(txt, status) # print the result
בוא נעבור לחלק 2 עכשיו שבו תבנה יותר על גבי הקוד הקיים שלך.
חלק 2: חילוץ כותרת עם BeautifulSoup
זהו הקישור למעבדה זו.
בכל הכיתה הזו, תשתמש בספרייה בשם BeautifulSoup
Python כדי לבצע גרידה באינטרנט. כמה תכונות שהופכות את BeautifulSoup לפיתרון רב עוצמה הן:
- הוא מספק הרבה שיטות פשוטות וניבים פיתוניים לניווט, חיפוש ושינוי עץ DOM. לא צריך הרבה קוד כדי לכתוב יישום
- מרק יפה יושב על גבי מנתחי פיתון פופולריים כמו lxml ו- html5lib, ומאפשרים לכם לנסות אסטרטגיות ניתוח שונות או מהירות סחר לצורך גמישות.
ביסודו של דבר, BeautifulSoup יכולה לנתח כל דבר באינטרנט שאתה נותן לו.
הנה דוגמה פשוטה ל- BeautifulSoup:
from bs4 import BeautifulSoup page = requests.get("//codedamn.com") soup = BeautifulSoup(page.content, 'html.parser') title = soup.title.text # gets you the text of the (...)
דרישות מעבר:
- השתמש
requests
בחבילה כדי להשיג כותרת כתובת האתר: //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/ - השתמש ב- BeautifulSoup כדי לאחסן את הכותרת של דף זה במשתנה שנקרא
page_title
אם מסתכלים על הדוגמה שלמעלה, תוכלו לראות ברגע שנאכיל את page.content
BeautifulSoup בפנים, תוכלו להתחיל לעבוד עם עץ ה- DOM המנותח בצורה פיתונית מאוד. הפיתרון למעבדה יהיה:
import requests from bs4 import BeautifulSoup # Make a request to //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/ page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Extract title of page page_title = soup.title.text # print the result print(page_title)
זו הייתה גם מעבדה פשוטה שבה היינו צריכים לשנות את כתובת האתר ולהדפיס את כותרת הדף. קוד זה יעבור במעבדה.
חלק 3: גוף וראש מרקים
זהו הקישור למעבדה זו.
במעבדה האחרונה ראית כיצד ניתן לחלץ title
את הדף. קל באותה מידה גם לחלץ חלקים מסוימים.
ראית גם שאתה צריך לקרוא .text
לאלה כדי להשיג את המחרוזת, אבל אתה יכול להדפיס אותם גם בלי להתקשר .text
, וזה ייתן לך את הסימון המלא. נסה להריץ את הדוגמה הבאה:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn.com") soup = BeautifulSoup(page.content, 'html.parser') # Extract title of page page_title = soup.title.text # Extract body of page page_body = soup.body # Extract head of page page_head = soup.head # print the result print(page_body, page_head)
בואו נסתכל איך אתה יכול לחלץ את body
ו head
קטעים מתוך הדפים שלך.
דרישות מעבר:
- חזור על הניסוי עם URL:
//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
- אחסן את שם העמוד (מבלי להתקשר לטקסט) של כתובת האתר ב
page_title
- אחסן תוכן גוף (בלי להתקשר לטקסט) של כתובת האתר ב
page_body
- אחסן תוכן ראש (מבלי להתקשר לטקסט) של כתובת האתר ב
page_head
כשאתה מנסה להדפיס את page_body
או, page_head
תראה שאלה מודפסים כ- strings
. אבל במציאות, print(type page_body)
כשתראה שזה לא מחרוזת אבל זה עובד בסדר.
הפתרון של דוגמה זו יהיה פשוט, על בסיס הקוד לעיל:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Extract title of page page_title = soup.title # Extract body of page page_body = soup.body # Extract head of page page_head = soup.head # print the result print(page_title, page_head)
חלק 4: בחר עם BeautifulSoup
זהו הקישור למעבדה זו.
כעת לאחר שבחנתם חלקים מסוימים ב- BeautifulSoup, בואו נראה כיצד תוכלו לבחור רכיבי DOM בשיטות BeautifulSoup.
Once you have the soup
variable (like previous labs), you can work with .select
on it which is a CSS selector inside BeautifulSoup. That is, you can reach down the DOM tree just like how you will select elements with CSS. Let's look at an example:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Extract first (...)
text first_h1 = soup.select('h1')[0].text
.select
returns a Python list of all the elements. This is why you selected only the first element here with the [0]
index.
Passing requirements:
- Create a variable
all_h1_tags
. Set it to empty list. - Use
.select
to select all thetags and store the text of those h1 inside
all_h1_tags
list. - Create a variable
seventh_p_text
and store the text of the 7thp
element (index 6) inside.
The solution for this lab is:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Create all_h1_tags as empty list all_h1_tags = [] # Set all_h1_tags to all h1 tags of the soup for element in soup.select('h1'): all_h1_tags.append(element.text) # Create seventh_p_text and set it to 7th p element text of the page seventh_p_text = soup.select('p')[6].text print(all_h1_tags, seventh_p_text)
Let's keep going.
Part 5: Top items being scraped right now
This is the link to this lab.
Let's go ahead and extract the top items scraped from the URL: //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/
If you open this page in a new tab, you’ll see some top items. In this lab, your task is to scrape out their names and store them in a list called top_items
. You will also extract out the reviews for these items as well.
To pass this challenge, take care of the following things:
- Use
.select
to extract the titles. (Hint: one selector for product titles could bea.title
) - Use
.select
to extract the review count label for those product titles. (Hint: one selector for reviews could bediv.ratings
) Note: this is a complete label (i.e. 2 reviews) and not just a number. - Create a new dictionary in the format:
info = { "title": 'Asus AsusPro Adv... '.strip(), "review": '2 reviews\n\n\n'.strip() }
- Note that you are using the
strip
method to remove any extra newlines/whitespaces you might have in the output. This is important to pass this lab. - Append this dictionary in a list called
top_items
- Print this list at the end
There are quite a few tasks to be done in this challenge. Let's take a look at the solution first and understand what is happening:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Create top_items as empty list top_items = [] # Extract and store in top_items according to instructions on the left products = soup.select('div.thumbnail') for elem in products: title = elem.select('h4 > a.title')[0].text review_label = elem.select('div.ratings')[0].text info = { "title": title.strip(), "review": review_label.strip() } top_items.append(info) print(top_items)
Note that this is only one of the solutions. You can attempt this in a different way too. In this solution:
- First of all you select all the
div.thumbnail
elements which gives you a list of individual products - Then you iterate over them
- Because
select
allows you to chain over itself, you can use select again to get the title. - Note that because you're running inside a loop for
div.thumbnail
already, theh4 > a.title
selector would only give you one result, inside a list. You select that list's 0th element and extract out the text. - Finally you strip any extra whitespace and append it to your list.
Straightforward right?
Part 6: Extracting Links
This is the link to this lab.
So far you have seen how you can extract the text, or rather innerText of elements. Let's now see how you can extract attributes by extracting links from the page.
Here’s an example of how to extract out all the image information from the page:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Create top_items as empty list image_data = [] # Extract and store in top_items according to instructions on the left images = soup.select('img') for image in images: src = image.get('src') alt = image.get('alt') image_data.append({"src": src, "alt": alt}) print(image_data)
In this lab, your task is to extract the href
attribute of links with their text
as well. Make sure of the following things:
- You have to create a list called
all_links
- In this list, store all link dict information. It should be in the following format:
info = { "href": "", "text": "" }
- Make sure your
text
is stripped of any whitespace - Make sure you check if your
.text
is None before you call.strip()
on it. - Store all these dicts in the
all_links
- Print this list at the end
You are extracting the attribute values just like you extract values from a dict, using the get
function. Let's take a look at the solution for this lab:
import requests from bs4 import BeautifulSoup # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Create top_items as empty list all_links = [] # Extract and store in top_items according to instructions on the left links = soup.select('a') for ahref in links: text = ahref.text text = text.strip() if text is not None else '' href = ahref.get('href') href = href.strip() if href is not None else '' all_links.append({"href": href, "text": text}) print(all_links)
Here, you extract the href
attribute just like you did in the image case. The only thing you're doing is also checking if it is None. We want to set it to empty string, otherwise we want to strip the whitespace.
Part 7: Generating CSV from data
This is the link to this lab.
Finally, let's understand how you can generate CSV from a set of data. You will create a CSV with the following headings:
- Product Name
- Price
- Description
- Reviews
- Product Image
These products are located in the div.thumbnail
. The CSV boilerplate is given below:
import requests from bs4 import BeautifulSoup import csv # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') all_products = [] products = soup.select('div.thumbnail') for product in products: # TODO: Work print("Work on product here") keys = all_products[0].keys() with open('products.csv', 'w',) as output_file: dict_writer = csv.DictWriter(output_file, keys) dict_writer.writeheader() dict_writer.writerows(all_products)
You have to extract data from the website and generate this CSV for the three products.
Passing Requirements:
- Product Name is the whitespace trimmed version of the name of the item (example - Asus AsusPro Adv..)
- Price is the whitespace trimmed but full price label of the product (example - $1101.83)
- The description is the whitespace trimmed version of the product description (example - Asus AsusPro Advanced BU401LA-FA271G Dark Grey, 14", Core i5-4210U, 4GB, 128GB SSD, Win7 Pro)
- Reviews are the whitespace trimmed version of the product (example - 7 reviews)
- Product image is the URL (src attribute) of the image for a product (example - /webscraper-python-codedamn-classroom-website/cart2.png)
- The name of the CSV file should be products.csv and should be stored in the same directory as your script.py file
Let's see the solution to this lab:
import requests from bs4 import BeautifulSoup import csv # Make a request page = requests.get( "//codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/") soup = BeautifulSoup(page.content, 'html.parser') # Create top_items as empty list all_products = [] # Extract and store in top_items according to instructions on the left products = soup.select('div.thumbnail') for product in products: name = product.select('h4 > a')[0].text.strip() description = product.select('p.description')[0].text.strip() price = product.select('h4.price')[0].text.strip() reviews = product.select('div.ratings')[0].text.strip() image = product.select('img')[0].get('src') all_products.append({ "name": name, "description": description, "price": price, "reviews": reviews, "image": image }) keys = all_products[0].keys() with open('products.csv', 'w',) as output_file: dict_writer = csv.DictWriter(output_file, keys) dict_writer.writeheader() dict_writer.writerows(all_products)
The for
block is the most interesting here. You extract all the elements and attributes from what you've learned so far in all the labs.
When you run this code, you end up with a nice CSV file. And that's about all the basics of web scraping with BeautifulSoup!
Conclusion
I hope this interactive classroom from codedamn helped you understand the basics of web scraping with Python.
If you liked this classroom and this blog, tell me about it on my twitter and Instagram. Would love to hear feedback!