W drugiej części wykorzystamy poprzedni wynik działania skryptu do dalszej obróbki i zabawy z python scraping’iem.
Zapis w postaci adresu IP nie wiele nam mówi. Najprostszym rozwiązaniem jest użycie polecenia whois:
whois IP
Otrzymamy mnóstwo informacji na temat adresu IP m.in. domeny do niego przypisanej, DNS’ów, właściciela itd. Ręczne sprawdzanie kilkunastu adresów jest jednak mało efektywne. Dla naszych potrzeb ograniczmy się do sprawdzenia informacji z pozycji “NetName” czyli nazwa serwera np.”google” . Warto wspomnieć, że jest pewien bałagan w informacjach zwrotnych jakie otrzymujemy, który komplikuje trochę zadanie. Niektóre wpisy nie zawierają “NetName”, a “descr” do tego pojawiają się duże i małe litery. Finalnie chcę uzyskać numer IP + nazwę serwera.
Fragment kodu odpowiedzialny za wydobycie informacji z polecenia whois:
def whois(ip, i): #tworzymy listę IP ip = str(ip[i]) #wyświetla pojedynczy adres IP print (ip) #sprawdzam pojjedynczy adres IP poleceniem whois who = check_output(['whois', ip], universal_newlines=True) #konwertuje wynik whois do małych liter who = who.lower() #sprawdzam czy w wyniku jest pozycja "descr" descr = who.find('descr') #dzielę tekst na pozycji "netname:" who = who.split('netname:')[1] #jeśli jest "descr" to na nim robię podział if descr > 1 : who = who.split('descr')[1] who = who.split('country')[0] #jeśli użyłem "netname" drugi podział na "nethandle" else: who = who.split('nethandle')[0] #usuwam zbędne znaki return who.replace(r'\n', '') #pętla przekazująca poszczególne elementy listy IP for item in range(0, len(ip)): print (whois(ip, item))
Większość rzeczy opisałem w komentarzach warto wspomnieć, że narzędzie split pozwala dzielić tekst na dwie części, a cyfra w nawiasie kwadratowym mówi nam, która część tekstu nas interesuje np.
Plecenie whois zwraca m.in.:
NetName: DROPBOX
NetHandle: NET-108-160-160-0-1
Nas interesuje tylko ciąg znaków “DROPBOX”. Działanie polecenia split jest takie:
who = who.split('netname:')[1] who = who.split('nethandle')[0]
NetName: < –[0]|[1]–> DROPBOX< –[0]|[1]–> NetHandle: NET-108-160-160-0-1
Jak widać Python ma wiele fajnych narzędzi do pracy z tekstem typu re, find, split itd. dzięki temu w łatwy sposób możemy wydobywać informacje, które nas interesują. Jeszcze połączę oba kody razem:
#!/usr/bin/python import subprocess import socket import re from subprocess import check_output # pozyskuję adtes ip karty w celu późniejszego odfiltrowania z netstat s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('8.8.8.8', 0)) # connecting to a UDP address doesn't send packets local_ip_address = s.getsockname()[0] local_ip = str(local_ip_address) #wykonuję polecenie netstat sprawdzające połączone adresy IP p = subprocess.Popen(['netstat', '-atn', '|', 'grep', 'ESTA' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() #obrabiam dane wejściowe ip = str(out) ip = ip.replace('127.0.0.1', '') ip = ip.replace(local_ip, '') ip = ip.replace('0.0.0.0', '') #wyszukuje adresy IP ip = re.findall( r'[0-9]+(?:\.[0-9]+){3}', ip ) def whois(ip, i): #tworzymy listę IP ip = str(ip[i]) #wyświetla pojedynczy adres IP print (ip) #sprawdzam pojjedynczy adres IP poleceniem whois who = check_output(['whois', ip], universal_newlines=True) #konwertuje wynik whois do małych liter who = who.lower() #sprawdzam czy w wyniku jest pozycja "descr" descr = who.find('descr') #dzielę tekst na pozycji "netname:" who = who.split('netname:')[1] #jeśli jest "descr" to na nim robię podział if descr > 1 : who = who.split('descr:')[1] who = who.split('country')[0] #jeśli użyłem "netname" drugi podział na "nethandle" else: who = who.split('nethandle')[0] #usuwam zbędne znaki return who.replace(r'\n', '') #pętla przekazująca poszczególne elementy listy IP for item in range(0, len(ip)): print (whois(ip, item))
Jest to baza do dalszej pracy, można na tej podstawie zbudować sobie np: program do statystyki odwiedzanych serwerów etc. Python scraping umożliwia w szybki i w miarę prosty sposób obróbki dowolnego tekstu, wszystko polega głównie na dobrej kolejności wykonania odpowiednich poleceń.
W następnych wpisach pokażę typowy web scraping.