írta: Ahad Sheriff
egyszerű projekt a webkaparás alapjainak megismeréséhez
mielőtt elkezdenénk, győződjünk meg róla, hogy megértjük, mi a webkaparás:
a Webkaparás az adatok kinyerésének folyamata a webhelyekről, hogy azokat olyan formátumban mutassuk be, amelyet a felhasználók könnyen megérthetnek.
ebben az oktatóanyagban azt szeretném bemutatni, hogy mennyire könnyű felépíteni egy egyszerű URL-bejárót a Pythonban, amelyet webhelyek térképezésére használhat. Bár ez a program viszonylag egyszerű, nagyszerű bevezetést nyújthat a webkaparás és az automatizálás alapjaihoz. Arra fogunk összpontosítani, hogy rekurzívan kivonjuk a linkeket a weboldalakról, de ugyanazok az ötletek számtalan más megoldásra alkalmazhatók.
programunk így fog működni:
- látogasson el egy weboldalra
- kaparja meg a weboldalon található összes egyedi URL-t, és vegye fel őket egy sorba
- rekurzív módon dolgozza fel az URL-eket egyesével, amíg kimerítjük a várólistát
- eredmények nyomtatása
az első dolgok először
az első dolog, amit meg kell tennünk, az összes a szükséges könyvtárak. A webes kaparáshoz a BeautifulSoup, a requests és az urllib alkalmazást fogjuk használni.
from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque
ezután ki kell választanunk egy URL-t, ahonnan elkezdhetjük a feltérképezést. Bár bármilyen weboldalt választhat HTML linkekkel, javaslom a ScrapeThisSite használatát. Ez egy biztonságos homokozó, amelyet feltérképezhet anélkül, hogy bajba kerülne.
url = "https://scrapethissite.com"
ezután létre kell hoznunk egy új deque objektumot, hogy könnyen hozzáadhassuk az újonnan talált linkeket, és eltávolítsuk őket, miután befejeztük a feldolgozásukat. Töltse fel előre a deque-t a url
változóval:
# a queue of urls to be crawled nextnew_urls = deque()
ezután használhatunk egy készletet az egyedi URL-ek tárolására, miután feldolgozták őket:
# a set of urls that we have already processed processed_urls = set()
szeretnénk nyomon követni a helyi (ugyanaz a domain, mint a cél), a külföldi (más domain, mint a cél), valamint a törött URL-eket:
# 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()
ideje feltérképezni
mindezt a helyén, most elkezdhetjük írni a tényleges kódot a webhely feltérképezéséhez.
meg akarjuk nézni a várólista minden URL-jét, hogy lássuk, vannak-e további URL-ek az Oldalon belül, és mindegyiket hozzá kell adni a sor végéhez, amíg egyik sem marad. Amint befejeztük az URL lekaparását, eltávolítjuk a sorból, és hozzáadjuk a processed_urls
készlethez későbbi felhasználás céljából.
# 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)
ezután adjon hozzá egy kivételt, hogy elkapja a törött weboldalakat, majd adja hozzá őket a broken_urls
készlethez későbbi használatra:
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
ezután meg kell szereznünk a weboldal alap URL-jét, hogy könnyen megkülönböztethessük a helyi és a külföldi címeket:
# 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
inicializálja a BeautifulSoup-ot a HTML dokumentum feldolgozásához:
soup = BeautifulSoup(response.text, "lxml")
most kaparja a weboldalt az összes linkhez, majd rendezze hozzá őket a megfelelő készlethez:
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)
mivel a robotomat csak a helyi címekre szeretném korlátozni, a következőket adom hozzá, hogy új URL-eket adjak a várólistánkhoz:
for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)
ha az összes URL-t fel szeretné térképezni, használja:
if not link in new_urls and not link in processed_urls: new_urls.append(link)
figyelem: A program jelenlegi működése, a külföldi URL-ek feltérképezése nagyon hosszú időt vesz igénybe. Akkor esetleg bajba kaparás honlapok engedély nélkül. Használja saját felelősségére!
itt van az összes kódom:
és ez legyen az. Most létrehozott egy egyszerű eszközt a webhely feltérképezéséhez és az összes megtalált URL feltérképezéséhez!
összefoglalva
nyugodtan építsen és javítsa ezt a kódot. Például módosíthatja a programot úgy, hogy a weboldalakon e-mail címeket vagy telefonszámokat keressen, miközben feltérképezi őket. Még a funkcionalitást is kibővítheti parancssori argumentumok hozzáadásával, hogy lehetőséget biztosítson a kimeneti fájlok meghatározására, a keresések mélységre korlátozására és még sok másra. Itt olvashat arról, hogyan hozhat létre parancssori interfészeket az argumentumok elfogadásához.