Tutorial Scraping Python Ιστού - Πώς να αποκόψετε δεδομένα από έναν ιστότοπο

Το Python είναι μια όμορφη γλώσσα για κωδικοποίηση. Έχει ένα υπέροχο οικοσύστημα πακέτων, υπάρχει πολύ λιγότερος θόρυβος από ό, τι θα βρείτε σε άλλες γλώσσες και είναι εξαιρετικά εύκολο στη χρήση.

Το Python χρησιμοποιείται για πολλά πράγματα, από την ανάλυση δεδομένων έως τον προγραμματισμό διακομιστή. Και μια συναρπαστική περίπτωση χρήσης του Python είναι το Web Scraping.

Σε αυτό το άρθρο, θα καλύψουμε τον τρόπο χρήσης του Python για απόξεση ιστού. Θα εργαστούμε επίσης μέσω ενός πλήρους πρακτικού οδηγού στην τάξη καθώς προχωράμε.

Σημείωση: Θα ανακαλύπτουμε μια ιστοσελίδα που φιλοξενώ, έτσι ώστε να μπορούμε να μάθουμε με ασφάλεια την απόκρυψή της. Πολλές εταιρείες δεν επιτρέπουν την απόσυρση στους ιστότοπούς τους, οπότε αυτός είναι ένας καλός τρόπος για να μάθετε. Απλά βεβαιωθείτε ότι έχετε ελέγξει πριν από την απόξεση.

Εισαγωγή στην τάξη Scraping Ιστού

Εάν θέλετε να κωδικοποιήσετε μαζί, μπορείτε να χρησιμοποιήσετε αυτήν την δωρεάν τάξη κωδικοποίησηςπου αποτελείται από πολλά εργαστήρια που θα σας βοηθήσουν να μάθετε τη δημιουργία ξύλου. Αυτό θα είναι μια πρακτική πρακτική άσκηση μάθησης στο codedamn, παρόμοιο με το πώς μαθαίνετε στο freeCodeCamp.

Σε αυτήν την τάξη, θα χρησιμοποιείτε αυτήν τη σελίδα για να δοκιμάσετε το ξύσιμο ιστού: //codedamn-classrooms.github.io/webscraper-python-codedamn-classroom-website/

Αυτή η τάξη αποτελείται από 7 εργαστήρια και θα λύσετε ένα εργαστήριο σε κάθε μέρος αυτής της ανάρτησης ιστολογίου. Θα χρησιμοποιήσουμε το Python 3.8 + BeautifulSoup 4 για το web scraping.

Μέρος 1: Φόρτωση ιστοσελίδων με "αίτημα"

Αυτός είναι ο σύνδεσμος προς αυτό το εργαστήριο.

Η requestsενότητα σάς επιτρέπει να στέλνετε αιτήματα HTTP χρησιμοποιώντας το Python.

Το αίτημα HTTP επιστρέφει ένα αντικείμενο απόκρισης με όλα τα δεδομένα απόκρισης (περιεχόμενο, κωδικοποίηση, κατάσταση και ούτω καθεξής). Ένα παράδειγμα λήψης του HTML μιας σελίδας:

import requests res = requests.get('//codedamn.com') print(res.text) print(res.status_code)

Απαιτήσεις επιτυχίας:

  • Λάβετε τα περιεχόμενα της ακόλουθης διεύθυνσης URL χρησιμοποιώντας την 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: Εξαγωγή τίτλου με το BeautifulSoup

Αυτός είναι ο σύνδεσμος προς αυτό το εργαστήριο.

Σε ολόκληρη την τάξη, θα χρησιμοποιείτε μια βιβλιοθήκη που ονομάζεται BeautifulSoupPython για να κάνετε web scraping Ορισμένες δυνατότητες που κάνουν το BeautifulSoup μια ισχυρή λύση είναι:

  1. Παρέχει πολλές απλές μεθόδους και Pythonic ιδιώματα για πλοήγηση, αναζήτηση και τροποποίηση ενός δέντρου DOM. Δεν χρειάζεται πολύς κώδικας για τη σύνταξη μιας εφαρμογής
  2. Το Beautiful Soup βρίσκεται στην κορυφή δημοφιλών αναλυτών Python όπως 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πακέτο για να αποκτήσετε τον τίτλο της διεύθυνσης URL: //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)

Αυτό ήταν επίσης ένα απλό εργαστήριο όπου έπρεπε να αλλάξουμε τη διεύθυνση URL και να εκτυπώσουμε τον τίτλο της σελίδας. Αυτός ο κωδικός θα περάσει από το εργαστήριο.

Μέρος 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/
  • Αποθηκεύστε τον τίτλο της σελίδας (χωρίς κλήση .text) του URL στο page_title
  • Αποθηκεύστε το περιεχόμενο του σώματος (χωρίς να καλέσετε .text) του URL στο page_body
  • Αποθηκεύστε το περιεχόμενο του κεφαλιού (χωρίς να καλέσετε .text) του URL στο 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 the

    tags and store the text of those h1 inside all_h1_tags list.

  • Create a variable seventh_p_text and store the text of the 7th p 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 be a.title)
  • Use .select to extract the review count label for those product titles. (Hint: one selector for reviews could be div.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:

  1. First of all you select all the div.thumbnail elements which gives you a list of individual products
  2. Then you iterate over them
  3. Because select allows you to chain over itself, you can use select again to get the title.
  4. Note that because you're running inside a loop for div.thumbnail already, the h4 > a.title selector would only give you one result, inside a list. You select that list's 0th element and extract out the text.
  5. 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:

  1. Product Name
  2. Price
  3. Description
  4. Reviews
  5. 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.

Αν σας άρεσε αυτή η τάξη και αυτό το blog, πείτε μου σχετικά με το twitter και το Instagram μου. Θα ήθελα πολύ να ακούσω σχόλια!