af Ahad Sheriff
et simpelt projekt til at lære de grundlæggende elementer i skrabning på nettet
før vi begynder, lad os sørge for, at vi forstår, hvad skrabning er:
skrabning er processen med at udtrække data fra hjemmesider for at præsentere det i et format, som brugerne nemt kan forstå.
i denne tutorial vil jeg demonstrere, hvor nemt det er at opbygge en simpel URL-larvebånd i Python, som du kan bruge til at kortlægge hjemmesider. Selvom dette program er relativt enkelt, kan det give en god introduktion til fundamentet for skrabning og automatisering på nettet. Vi vil fokusere på rekursivt at udtrække links fra hjemmesider, men de samme ideer kan anvendes på et utal af andre løsninger.
vores program vil fungere som dette:
- besøg en hjemmeside
- Skrab alle unikke URL ‘er fundet på hjemmesiden og tilføj dem til en kø
- rekursivt behandle URL’ er en efter en, indtil vi udtømmer køen
- Udskriv resultater
første ting først
den første ting, vi skal gøre, er at Importer alle de nødvendige biblioteker. Vi vil bruge BeautifulSoup, anmodninger og urllib til skrabning på nettet.
from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque
Dernæst skal vi vælge en URL for at begynde at kravle fra. Mens du kan vælge en hjemmeside med HTML-links, anbefaler jeg at bruge ScrapeThisSite. Det er en sikker sandkasse, som du kan kravle uden at komme i problemer.
url = "https://scrapethissite.com"
Dernæst skal vi oprette et nyt dekeobjekt, så vi nemt kan tilføje nyligt fundne links og fjerne dem, når vi er færdige med at behandle dem. Pre-udfylde deket med din url
variabel:
# a queue of urls to be crawled nextnew_urls = deque()
vi kan derefter bruge et sæt til at gemme unikke URL ‘er, når de er blevet behandlet:
# a set of urls that we have already processed processed_urls = set()
vi ønsker også at holde styr på lokalt (samme domæne som målet), udenlandsk (andet domæne som målet) og ødelagte URL’ er:
# 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()
tid til at gennemgå
med alt det på plads kan vi nu begynde at skrive den faktiske kode for at gennemgå hjemmesiden.
vi vil se på hver URL i køen, se om der er yderligere URL ‘ er på den side og tilføje hver til slutningen af køen, indtil der ikke er nogen tilbage. Så snart vi er færdige med at skrabe en URL, fjerner vi den fra køen og tilføjer den til processed_urls
– sættet til senere brug.
# 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)
tilføj derefter en undtagelse for at fange eventuelle ødelagte hjemmesider og tilføj dem til broken_urls
sæt til senere brug:
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
vi skal derefter få basis-URL ‘en på hjemmesiden, så vi nemt kan differentiere lokale og udenlandske adresser:
# 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 if '/' in parts.path else url
Initialiser BeautifulSoup for at behandle HTML-dokumentet:
soup = BeautifulSoup(response.text, "lxml")
nu skrabe hjemmesiden for alle links og sortere tilføje dem til deres tilsvarende sæt:
for link in soup.find_all('a'): # extract link url from the anchor anchor = link.attrs 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)
da jeg kun vil begrænse min Larvebånd til lokale adresser, tilføjer jeg følgende for at tilføje nye URL’ er til vores kø:
for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)
hvis du vil gennemgå alle URL ‘ er brug:
if not link in new_urls and not link in processed_urls: new_urls.append(link)
advarsel: Den måde, programmet i øjeblikket fungerer på, vil gennemgå udenlandske URL ‘ er tage meget lang tid. Du kan muligvis komme i problemer for at skrabe hjemmesider uden tilladelse. Brug på egen risiko!
her er al min kode:
og det burde være det. Du har lige oprettet et simpelt værktøj til at gennemgå en hjemmeside og kortlægge alle URL ‘ er fundet!
afslutningsvis
du er velkommen til at bygge videre på og forbedre denne kode. For eksempel kan du ændre programmet for at søge på hjemmesider efter e-mail-adresser eller telefonnumre, mens du gennemsøger dem. Du kan endda udvide funktionaliteten ved at tilføje kommandolinjeargumenter for at give mulighed for at definere outputfiler, begrænse søgninger til dybde og meget mere. Lær om, hvordan du opretter kommandolinjegrænseflader for at acceptere argumenter her.