Πώς να δημιουργήσετε ένα πρόγραμμα ανίχνευσης URL για να χαρτογραφήσετε έναν ιστότοπο χρησιμοποιώντας το Python

Ένα απλό έργο για την εκμάθηση των βασικών στοιχείων του web scraping

Πριν ξεκινήσουμε, ας βεβαιωθούμε ότι καταλαβαίνουμε τι είναι το scraping ιστού:

Το web scraping είναι η διαδικασία εξαγωγής δεδομένων από ιστότοπους για παρουσίαση σε μορφή που οι χρήστες μπορούν να κατανοήσουν εύκολα.

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

Το πρόγραμμά μας θα λειτουργεί ως εξής:

  1. Επισκεφθείτε μια ιστοσελίδα
  2. Ξύστε όλα τα μοναδικά URL που βρίσκονται στην ιστοσελίδα και προσθέστε τα σε μια ουρά
  3. Επεξεργαστείτε αναδρομικά το URL ένα προς ένα έως ότου εξαντλήσουμε την ουρά
  4. Εκτύπωση αποτελεσμάτων

Καταρχάς

Το πρώτο πράγμα που πρέπει να κάνουμε είναι να εισαγάγουμε όλες τις απαραίτητες βιβλιοθήκες. Θα χρησιμοποιούμε το BeautifulSoup, αιτήματα και urllib για το web scraping.

from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque

Στη συνέχεια, πρέπει να επιλέξουμε μια διεύθυνση URL για να ξεκινήσουμε την ανίχνευση. Ενώ μπορείτε να επιλέξετε οποιαδήποτε ιστοσελίδα με συνδέσμους HTML, σας προτείνω να χρησιμοποιήσετε το ScrapeThisSite. Είναι ένα ασφαλές περιβάλλον άμμου που μπορείτε να ανιχνεύσετε χωρίς να μπείτε σε μπελάδες.

url = “//scrapethissite.com”

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

# a queue of urls to be crawled nextnew_urls = deque([url])

Στη συνέχεια, μπορούμε να χρησιμοποιήσουμε ένα σύνολο για να αποθηκεύσουμε μοναδικές διευθύνσεις URL μετά την επεξεργασία τους:

# a set of urls that we have already processed processed_urls = set()

Θέλουμε επίσης να παρακολουθούμε τοπικά (ίδιο τομέα με τον στόχο), ξένο (διαφορετικό τομέα με τον στόχο) και κατεστραμμένα URL:

# a set of domains inside the target websitelocal_urls = set()
# a set of domains outside the target websiteforeign_urls = set()
# a set of broken urlsbroken_urls = set()

Ώρα για ανίχνευση

Με όλα αυτά, μπορούμε τώρα να αρχίσουμε να γράφουμε τον πραγματικό κώδικα για να ανιχνεύσουμε τον ιστότοπο.

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

# process urls one by one until we exhaust the queuewhile len(new_urls): # move url from the queue to processed url set url = new_urls.popleft() processed_urls.add(url) # print the current url print(“Processing %s” % url)

Στη συνέχεια, προσθέστε μια εξαίρεση για να πιάσετε τυχόν σπασμένες ιστοσελίδες και προσθέστε τις στο broken_urlsσύνολο για μελλοντική χρήση:

try: response = requests.get(url)
except(requests.exceptions.MissingSchema, requests.exceptions.ConnectionError, requests.exceptions.InvalidURL, requests.exceptions.InvalidSchema): # add broken urls to it’s own set, then continue broken_urls.add(url) continue

Στη συνέχεια, πρέπει να λάβουμε τη βασική διεύθυνση URL της ιστοσελίδας, ώστε να μπορούμε εύκολα να διαφοροποιήσουμε τις τοπικές και ξένες διευθύνσεις:

# extract base url to resolve relative linksparts = urlsplit(url)base = “{0.netloc}”.format(parts)strip_base = base.replace(“www.”, “”)base_url = “{0.scheme}://{0.netloc}”.format(parts)path = url[:url.rfind(‘/’)+1] if ‘/’ in parts.path else url

Αρχικοποιήστε το BeautifulSoup για να επεξεργαστείτε το έγγραφο HTML:

soup = BeautifulSoup(response.text, “lxml”)

Τώρα, ξύστε την ιστοσελίδα για όλους τους συνδέσμους και ταξινομήστε τις στο αντίστοιχο σύνολο:

for link in soup.find_all(‘a’): # extract link url from the anchor anchor = link.attrs[“href”] if “href” in link.attrs else ‘’
if anchor.startswith(‘/’): local_link = base_url + anchor local_urls.add(local_link) elif strip_base in anchor: local_urls.add(anchor) elif not anchor.startswith(‘http’): local_link = path + anchor local_urls.add(local_link) else: foreign_urls.add(anchor)

Εφόσον θέλω να περιορίσω το πρόγραμμα ανίχνευσης μόνο σε τοπικές διευθύνσεις, προσθέτω τα ακόλουθα για να προσθέσω νέες διευθύνσεις URL στην ουρά μας:

for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)

Αν θέλετε να ανιχνεύσετε όλες τις διευθύνσεις URL χρησιμοποιήστε:

if not link in new_urls and not link in processed_urls: new_urls.append(link)

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

Εδώ είναι όλο ο κωδικός μου:

Και αυτό πρέπει να είναι. Μόλις δημιουργήσατε ένα απλό εργαλείο για να ανιχνεύσετε έναν ιστότοπο και να χαρτογραφήσετε όλες τις διευθύνσεις URL που βρέθηκαν!

Συμπερασματικά

Μη διστάσετε να αναπτύξετε και να βελτιώσετε αυτόν τον κώδικα. Για παράδειγμα, μπορείτε να τροποποιήσετε το πρόγραμμα για να αναζητήσετε ιστοσελίδες σε διευθύνσεις email ή αριθμούς τηλεφώνου καθώς τις ανιχνεύετε. Θα μπορούσατε ακόμη και να επεκτείνετε τη λειτουργικότητα προσθέτοντας ορίσματα γραμμής εντολών για να παρέχετε την επιλογή να ορίσετε αρχεία εξόδου, να περιορίσετε τις αναζητήσεις σε βάθος και πολλά άλλα. Μάθετε πώς μπορείτε να δημιουργήσετε διεπαφές γραμμής εντολών για να αποδεχτείτε επιχειρήματα εδώ.

Εάν έχετε επιπλέον προτάσεις, συμβουλές ή πόρους, μοιραστείτε τα σχόλια!

Ευχαριστώ για την ανάγνωση! Εάν σας άρεσε αυτό το σεμινάριο και θέλετε περισσότερο περιεχόμενο όπως αυτό, φροντίστε να σπάσετε το παρακάτω κουμπί. ❤️

Επίσης, φροντίστε να δείτε τον ιστότοπό μου, το Twitter, το LinkedIn και το Github.