Cum se construiește un crawler URL pentru a mapa un site web folosind Python

de Ahad Sheriff

un proiect simplu pentru învățarea fundamentelor razuirii web

înainte de a începe, să ne asigurăm că înțelegem ce este răzuirea web:

răzuirea Web este procesul de extragere a datelor de pe site-uri web pentru a le prezenta într-un format pe care utilizatorii îl pot înțelege cu ușurință.

în acest tutorial, vreau să demonstrez cât de ușor este să construiți un crawler URL simplu în Python pe care îl puteți utiliza pentru a mapa site-urile web. Deși acest program este relativ simplu, poate oferi o introducere excelentă în fundamentele razuirii și automatizării web. Ne vom concentra pe extragerea recursivă a linkurilor din paginile web, dar aceleași idei pot fi aplicate la o multitudine de alte soluții.

programul nostru va funcționa astfel:

  1. vizitați o pagină web
  2. răzuiți toate URL-urile unice găsite pe pagina web și adăugați-le la o coadă
  3. procesați recursiv URL-ul unul câte unul până când epuizăm coada
  4. tipăriți rezultatele

primele lucruri mai întâi

primul lucru pe care ar trebui să-l facem este să importăm toate bibliotecile necesare. Vom folosi BeautifulSoup, cereri și urllib pentru razuire web.

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

în continuare, trebuie să selectăm o adresă URL din care să începem să accesăm cu crawlere. În timp ce puteți alege orice pagină web cu link-uri HTML, vă recomand să utilizați ScrapeThisSite. Este o cutie de nisip sigură pe care o puteți accesa cu crawlere fără a avea probleme.

url = "https://scrapethissite.com"

în continuare, va trebui să creăm un nou obiect deque, astfel încât să putem adăuga cu ușurință linkuri nou găsite și să le eliminăm odată ce le-am terminat de procesat. Pre-populați deque cu variabila url :

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

putem folosi apoi un set pentru a stoca URL-ul unic după ce au fost procesate:

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

de asemenea, dorim să urmărim adresele URL locale (același domeniu ca ținta), străine (domeniu diferit ca țintă) și rupte:

# 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()

e timpul să accesăm cu crawlere

cu toate acestea, putem începe acum să scriem codul real pentru a accesa cu crawlere site-ul web.

vrem să ne uităm la fiecare URL din coadă, să vedem dacă există URL-uri suplimentare în acea pagină și să le adăugăm pe fiecare la sfârșitul cozii până când nu mai rămân niciunul. De îndată ce terminăm răzuirea unei adrese URL, o vom elimina din coadă și o vom adăuga la setul processed_urls pentru o utilizare ulterioară.

# 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)

apoi, adăugați o excepție pentru a prinde orice pagini web rupte și adăugați-le la broken_urls setat pentru o utilizare ulterioară:

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

apoi trebuie să obținem adresa URL de bază a paginii web, astfel încât să putem diferenția cu ușurință adresele locale și străine:

# 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

inițializa BeautifulSoup pentru a procesa documentul HTML:

soup = BeautifulSoup(response.text, "lxml")

acum răzuiți pagina web pentru toate linkurile și sortați-le adăugați la setul corespunzător:

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)

deoarece vreau să-mi limitez crawlerul doar la adresele locale, adaug următoarele pentru a adăuga adrese URL noi la coada noastră:

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

dacă doriți să accesați cu crawlere toate adresele URL utilizați:

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

avertisment: Modul în care programul funcționează în prezent, accesarea cu crawlere a adresei URL străine va dura foarte mult timp. Ați putea avea probleme pentru răzuirea site-urilor web fără permisiune. Utilizați pe propriul risc!

exemplu de ieșire

aici este tot codul meu:

și asta ar trebui să fie. Tocmai ați creat un instrument simplu pentru a accesa cu crawlere un site web și harta toate adresele URL găsite!

în concluzie

Simțiți-vă liber să construiți și să îmbunătățiți acest cod. De exemplu, puteți modifica programul pentru a căuta pagini web adrese de e-mail sau numere de telefon în timp ce le accesați cu crawlere. Puteți chiar extinde funcționalitatea adăugând argumente în linia de comandă pentru a oferi opțiunea de a defini fișierele de ieșire, de a limita căutările la adâncime și multe altele. Aflați despre cum să creați interfețe de linie de comandă pentru a accepta argumente aici.

Write a Comment

Adresa ta de email nu va fi publicată.