Böngéssz Pythonban!

2014.01.07. | írta: kresshy

Ideje elvinni kicsit más irányba is a blog tartalmát, mivel az utóbbi időben jóformán csak front-end téma került elő. Mindig is foglalkoztatott az, hogy programozottan tudjam böngészni az világhálót. Ne gondoljunk rögtön a teljes internetet bejáró robotra, ezt a feladatot hagyjuk meg a Google-nek. Mi csak egy oldalra koncentrálunk erről szeretnénk lekérni, kiolvasni a tartalmát, megnézni a linkeket, letölteni róla egy-két fájlt, esetleg formokat kitölteni és elküldeni. A segítségünkre lesz a Python mint script nyelv és két modulja; a mechanize, és a BeautifulSoup. Előbbivel egy böngészőt tudunk szimulálni, utóbbival pedig a HTML oldal elemeit tudjuk feldolgozni.

mechanize

Programozott webböngészést tesz lehetővé és képes a böngésző állapotainak a megvalósítására is: navigációs előzmények, HTML form állapotok, cookie-k stb. A mechanize Andy Lester Perlben írt WWW::Mechanize moduljának Python átirata.

Lássuk azt a böngészőt!

Kifejezetten egyszerű használni a modult, nincs is más dolgunk mint importálni és meghívni a megfelelő függvényeket, amelyek mondhatni önmagukért beszélnek.

import mechanize
import cookielib

br = mechanize.Browser()
cj = cookielib.LWPCookieJar()
br.set_cookiejar(cj)

Kész is a böngészőnk! Nem is olyan nehéz, és a következőkben ennél csak könnyebb lesz. Mielőtt tovább mennénk, nézzük meg mi történik. Gyakorlatilag létrejön egy Browser objektumunk és a cookielib lesz a felelős a Browser által tárolt cookiek (sütik) kezeléséért. Ez az objektum olyan, mint egy grafikus felület nélküli böngésző. Megvannak a szükséges metódusai, amiket ha kivezetnénk egy felhasználói felületre, akkor egy kész böngészőt kapnánk. Mielőtt még elmerülünk a programozott böngészés világában, nézzük meg milyen beállítási lehetőségei vannak az objektumunknak:

# Browser beállítások
br.set_handle_equiv(True)
br.set_handle_gzip(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)

# Frissítések
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)

# Debug üzenetek
#br.set_debug_http(True)
#br.set_debug_redirects(True)
#br.set_debug_responses(True)

# User-Agent (egy kis csalás :])
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]

A legtöbb egyértelmű, de az utolsó érdekes. A User-Agent gyakorlatilag egy szoftver, ami a felhasználó nevében tevékenykedik. A böngészőkben, az e-mail kliensekben mind megtalálható. Nagyon sok esetben a User-Agent kliensként viselkedik egy hálózati protokollban a kommunikáció során - például a kliens-szerver architektúrában.

A fentieket ismerve elkezdhetünk játszani a böngészőnkkel. Van egy open(url) metódusa, amivel oldalakat tudsz megnyitni majd a response() függvényéből kapjuk meg a választ. Az open() után közvetlenül meghívva a response().read() függvényeket láthatjuk a letöltött oldal forrását. A title() függvénnyel ki tudjuk írni az oldal címét, az info() függvénnyel a header tartalmát tudjuk megnézni és így tovább. Az oldalon található formokat a forms() függvénnyel tudjuk lekérni ami egy listát szolgáltat a formok neveivel. Nézzük meg mennyire egyszerű kiválasztani egy formot!

# egy oldal letöltése
url = "http://kir-dev.sch.bme.hu"
response = br.open(url)
html = br.response().read()
print html

# Listázza a formokat
for f in br.forms():
    print f

# Kiválasztjuk az első formot
br.select_form(nr=0)

# A form egy mezőjébe beleírunk valamit majd submitoljuk
br.form['q']='random stuff'
br.submit()

# koilvassuk a kapott választ
print br.response().read()

Remek, de azért egy weboldal több dologból áll, mint puszta formok tömkelegéből. Mindenre van megoldás, követni tudjuk a linkeket, le tudunk tölteni fájlokat, a lehetőségeknek csak a képzeleted szab határt. A letöltésnél vigyázzunk, mert sok helyen a direkt linkeknél ha nincs beállítva a cookie kezelése, akkor feldobhat captchat a cél oldal (ellenőrző mezők, hogy nem robot vagy-e, itt az a baj, hogy lényegében az vagy). Ezeket a linkeket nem a retrive() függvénnyel kell letölteni hanem ténylegesen rá is kell kattintani a click_link() függvénnyel. Ilyenkor ellenőrzésre kerül a már említett cookie tartalma, és máris hozzá tudunk férni a letöltendő fájlhoz (elképzelhető, hogy nem cookie-val van megoldva, ez csak egy megoldás a sok lehetséges közül). A linkeket is lehetőségünk van ugyanúgy kilistázni akárcsak a formokat: for link in br.links(regex)!

# A link létezésének a vizsgálata
br.find_link(text='kir-dev')

# Ténylegesen rákattintunk a linkre
req = br.click_link(text='kir-dev')
br.open(req)
print br.response().read()
print br.geturl()

# Vissza
br.back()
print br.response().read()
print br.geturl()

# Letöltés
f = br.retrieve('kir-dev.sch.bme.hu/eznemletezik.gif')[0]
print f
fh = open(f)

Arra is képes, hogy proxy-t állítsunk be a böngészőnek!

# Proxy és felhasználónév/jelszó
br.set_proxies({"http": "joe:password@myproxy.example.com:3128"})

# Proxy
br.set_proxies({"http": "myproxy.example.com:3128"})
# Proxy jelszó
br.add_proxy_password("joe", "password")

A mechanize egy nagyon hasznos eszköz tud lenni a megfelelő ember kezében, képes automatizáltan böngészni a weboldalt, magára az oldalra tekinthetünk egy nagy gráfként, ahol az oldalak a csomópontok, és az élek az oldalon található linkek. Innentől az egésznek a bejárása gyerekjáték a már tanult módszerekkel (segítség: BFS, DFS).

BeautifulSoup

Képes parse-olni a HTML és XML fájlokat, beleértve az aszimmetrikus tageket is. A segítségével képesek vagyunk feldolgozni a HTML oldalt, keresni benne különböző elemeket (figyelembe véve az attribútumokat is), ezeknek a tartalmát kiszedni, linkeket keresni stb. Érdemes együtt használni a mechanize modullal. Miután a mechanize-zal megnyitottunk egy weboldalt a forrását át kell adjuk a BeautifulSoupnak:

response = br.open(url)
html = br.response().read()
soup = BeautifulSoup.BeautifulSoup(html)

Innentől kereshetünk az oldalon bármire:

soup.findAll('td', attrs={"class": "prodSpecAtribute"})

# linkek megkeresése az oldalon
links = soup.findAll("a")

for link in links:
    print link.contents[0], link.get("href")

Összességében két nagyon jól elkészített modulról van szó, amelyek képesek megkönnyíteni az életünket, ha már ilyen dolgokba kell belevágnunk. Magára a böngészésre a mechanize modult érdemes használni és az egyéb információk kinyerésére pedig a BeautifulSoupot. Böngésszetek programozottan!

Facebook Twitter Google+
comments powered by Disqus