av Ahad Sheriff
ett enkelt projekt för att lära sig grunderna i webbskrapning
innan vi börjar, låt oss se till att vi förstår vad webbskrapning är:
webbskrapning är processen att extrahera data från webbplatser för att presentera det i ett format som användare enkelt kan förstå.
i denna handledning vill jag visa hur lätt det är att bygga en enkel URL-sökrobot i Python som du kan använda för att kartlägga webbplatser. Även om detta program är relativt enkelt kan det ge en bra introduktion till grunderna för webbskrapning och automatisering. Vi kommer att fokusera på rekursivt extrahera länkar från webbsidor, men samma ideer kan tillämpas på en myriad av andra lösningar.
vårt program kommer att fungera så här:
- besök en webbsida
- skrapa alla unika URL: er som finns på webbsidan och Lägg till dem i en kö
- rekursivt bearbeta URL: er en efter en tills vi uttömmer kön
- utskriftsresultat
första saker först
det första vi bör göra är att importera alla nödvändiga bibliotek. Vi kommer att använda BeautifulSoup, förfrågningar och urllib för webbskrapning.
from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque
Därefter måste vi välja en URL för att börja krypa från. Medan du kan välja vilken webbsida som helst med HTML-länkar rekommenderar jag att du använder ScrapeThisSite. Det är en säker sandlåda som du kan krypa utan att få problem.
url = "https://scrapethissite.com"
Därefter måste vi skapa ett nytt deque-objekt så att vi enkelt kan lägga till nyfunna länkar och ta bort dem när vi är färdiga med att bearbeta dem. Pre-fylla deque med url
variabel:
# a queue of urls to be crawled nextnew_urls = deque()
vi kan sedan använda en uppsättning för att lagra unika webbadresser när de har bearbetats:
# a set of urls that we have already processed processed_urls = set()
vi vill också hålla reda på lokal (samma domän som målet), utländsk( annan domän som målet) och trasiga webbadresser:
# 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()
dags att krypa
med allt det på plats kan vi nu börja skriva den faktiska koden för att genomsöka webbplatsen.
vi vill titta på varje webbadress i kön, se om det finns några ytterligare webbadresser på den sidan och lägga till var och en i slutet av kön tills det inte finns någon kvar. Så snart vi har skrapat en URL tar vi bort den från kön och lägger till den i processed_urls
– uppsättningen för senare användning.
# 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)
lägg sedan till ett undantag för att fånga några trasiga webbsidor och Lägg till dem i broken_urls
– uppsättningen för senare användning:
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 måste sedan få webbsidans basadress så att vi enkelt kan skilja lokala och utländska 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
initiera BeautifulSoup för att bearbeta HTML-dokumentet:
soup = BeautifulSoup(response.text, "lxml")
skrapa nu webbsidan för alla länkar och sortera Lägg till dem i motsvarande uppsättning:
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)
eftersom jag bara vill begränsa min sökrobot till lokala adresser lägger jag till följande för att lägga till nya webbadresser i vår kö:
for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)
om du vill genomsöka alla webbadresser använder du:
if not link in new_urls and not link in processed_urls: new_urls.append(link)
Varning: Det sätt på vilket programmet för närvarande fungerar, kommer att genomsöka utländska URL-adresser ta mycket lång tid. Du kan eventuellt komma i trubbel för att skrapa webbplatser utan tillstånd. Använd på egen risk!
här är all min kod:
och det borde vara det. Du har just skapat ett enkelt verktyg för att genomsöka en webbplats och kartlägga alla webbadresser som hittats!
Sammanfattningsvis
Känn dig fri att bygga vidare på och förbättra denna kod. Du kan till exempel ändra programmet för att söka efter webbsidor efter e-postadresser eller telefonnummer när du genomsöker dem. Du kan till och med utöka funktionaliteten genom att lägga till kommandoradsargument för att ge möjlighet att definiera utdatafiler, begränsa sökningar till djup och mycket mer. Läs om hur du skapar kommandoradsgränssnitt för att acceptera argument här.