Ahad Sheriff
prosty projekt do nauki podstaw skrobania stron internetowych
zanim zaczniemy, upewnijmy się, że rozumiemy, czym jest skrobanie internetowe:
skrobanie internetowe to proces wyodrębniania danych ze stron internetowych w celu zaprezentowania ich w formacie, który użytkownicy mogą łatwo zrozumieć.
w tym samouczku chcę zademonstrować, jak łatwo jest zbudować prosty indeks URL w Pythonie, który można wykorzystać do mapowania stron internetowych. Chociaż ten program jest stosunkowo prosty,może stanowić świetne wprowadzenie do podstaw skrobania i automatyzacji sieci. Skupimy się na rekurencyjnym wyodrębnianiu linków ze stron internetowych, ale te same pomysły można zastosować do niezliczonej liczby innych rozwiązań.
nasz program będzie działał tak:
- odwiedź stronę internetową
- Zeskrobaj wszystkie unikalne adresy URL znalezione na stronie internetowej i dodaj je do kolejki
- rekurencyjnie przetwarzaj adresy URL jeden po drugim, aż wyczerpiemy kolejkę
- Drukuj wyniki
pierwsze rzeczy po kolei
pierwszą rzeczą, którą powinniśmy zrobić, to Importuj wszystkie niezbędne biblioteki. Będziemy używać BeautifulSoup, requests i urllib do skrobania stron internetowych.
from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque
następnie musimy wybrać adres URL, z którego zaczniemy indeksować. Chociaż możesz wybrać dowolną stronę internetową z linkami HTML, polecam użycie ScrapeThisSite. Jest to bezpieczna piaskownica, którą możesz czołgać się bez kłopotów.
url = "https://scrapethissite.com"
następnie będziemy musieli utworzyć nowy obiekt deque, abyśmy mogli łatwo dodać nowo znalezione linki i usunąć je po zakończeniu ich przetwarzania. Wstępnie wypełnij deque swoją zmienną url
:
# a queue of urls to be crawled nextnew_urls = deque()
następnie możemy użyć zestawu do przechowywania unikalnych adresów URL po ich przetworzeniu:
# a set of urls that we have already processed processed_urls = set()
chcemy również śledzić lokalne (ta sama domena co docelowa), zagraniczne (Inna domena jako docelowa) i uszkodzone adresy 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()
czas na indeksowanie
mając to wszystko na miejscu, możemy teraz zacząć pisać rzeczywisty kod, aby indeksować stronę.
chcemy przyjrzeć się każdemu adresowi URL w kolejce, sprawdzić, czy na tej stronie są jakieś dodatkowe adresy URL i dodać każdy z nich do końca kolejki, dopóki nie zostanie żaden. Jak tylko zakończymy skrobanie adresu URL, usuniemy go z kolejki i dodamy do zestawu processed_urls
do późniejszego użycia.
# 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)
następnie Dodaj wyjątek, aby złapać uszkodzone strony internetowe i dodać je do zestawu broken_urls
do późniejszego użycia:
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
następnie musimy uzyskać podstawowy adres URL strony internetowej, abyśmy mogli łatwo odróżnić adresy lokalne i zagraniczne:
# 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
Zainicjuj BeautifulSoup, aby przetworzyć dokument HTML:
soup = BeautifulSoup(response.text, "lxml")
teraz zeskrobaj stronę dla wszystkich linków i sortuj dodaj je do odpowiedniego zestawu:
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)
ponieważ chcę ograniczyć mój Robot tylko do adresów lokalnych, dodaję następujące, aby dodać nowe adresy URL do naszej kolejki:
for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)
jeśli chcesz przeszukiwać wszystkie adresy URL użyj:
if not link in new_urls and not link in processed_urls: new_urls.append(link)
Ostrzeżenie: Sposób, w jaki program obecnie działa, indeksowanie zagranicznych adresów URL zajmie bardzo dużo czasu. Możesz mieć problemy ze skrobaniem stron internetowych bez zgody. Używaj na własne ryzyko!
oto cały mój kod:
i to powinno być to. Właśnie stworzyłeś proste narzędzie do indeksowania strony i mapowania wszystkich znalezionych adresów URL!
Podsumowując
zapraszam do budowania i ulepszania tego kodu. Możesz na przykład zmodyfikować program, aby przeszukiwał strony internetowe pod kątem adresów e-mail lub numerów telefonów podczas ich indeksowania. Możesz nawet rozszerzyć funkcjonalność, dodając argumenty wiersza poleceń, aby zapewnić opcję definiowania plików wyjściowych, ograniczenia wyszukiwania do głębi i wiele więcej. Dowiedz się, jak tworzyć interfejsy wiersza poleceń do akceptowania argumentów tutaj.