2008-11-19 17 views
52

Próbuję przetestować funkcjonalność aplikacji internetowej poprzez skryptowanie sekwencji logowania w Pythonie, ale mam pewne problemy.Python: urllib/urllib2/httplib confusion

Oto co trzeba zrobić:

  1. Czy POST z kilku parametrów i nagłówków.
  2. Wykonaj przekierowanie
  3. Pobierz treść HTML.

Teraz jestem stosunkowo nowy w Pythonie, ale dwie rzeczy, które testowałem do tej pory, nie zadziałały. Najpierw użyłem httplib, z putrequest() (przekazując parametry w URL) i putheader(). Wygląda na to, że nie podąża za przekierowaniami.

Potem próbowałem urllib i urllib2, przekazując oba nagłówki i parametry jako dyktanda. Wydaje się, że zwraca stronę logowania, zamiast strony, na którą próbuję się zalogować, chyba ze względu na brak plików cookie lub coś podobnego.

jestem brakuje czegoś proste?

Dzięki.

+1

Użyj biblioteki żądań Pythona. – hughdbrown

Odpowiedz

31

Skoncentruj się na urllib2 do tego, działa całkiem dobrze. Nie zadzieraj z httplib, to nie jest interfejs API najwyższego poziomu.

Podkreślamy, że urllib2 nie wykonuje przekierowania.

Musisz złożyć wystąpienie HTTPRedirectHandler, które będzie przechwytywać i śledzić przekierowania.

Ponadto możesz podklasować domyślne HTTPRedirectHandler, aby przechwycić informacje, które następnie sprawdzisz jako część testów jednostkowych.

cookie_handler= urllib2.HTTPCookieProcessor(self.cookies) 
redirect_handler= HTTPRedirectHandler() 
opener = urllib2.build_opener(redirect_handler,cookie_handler) 

Następnie można użyć tego opener obiekt do POST i GET, obsługi przekierowań i ciasteczka prawidłowo.

Możesz również dodać własną podklasę HTTPHandler, aby przechwytywać i rejestrować różne kody błędów.

+12

urllib2.urlopen wydaje się dobrze obsługiwać przekierowania. –

+0

@Sridhar Również to znalazłem - urllib2.urlopen doskonale sprawdza przekierowania. – mikemaccana

0

Oprócz faktu, że może brakować pliku cookie, w formularzu mogą być pola (pola), które nie są POSTINGiem do serwera WWW. Najlepszym sposobem byłoby przechwycenie rzeczywistego POST z przeglądarki internetowej. Możesz użyć LiveHTTPHeaders lub WireShark, aby wsłuchać się w ruch i naśladować to samo zachowanie w swoim skrypcie.

+0

Dzięki za dobrą końcówkę dodatku Firefox :) Ale nie, wydaje mi się, że przekazuję niezbędne nagłówki i dane. – Ace

6

Wypróbuj twill - prosty język, który umożliwia użytkownikom przeglądanie Internetu za pomocą interfejsu wiersza poleceń. Dzięki twill możesz poruszać się po stronach internetowych, które używają formularzy, plików cookie i większości standardowych funkcji internetowych. Więcej do punktu, skośnym jest napisane w Python i ma python API, np:

from twill import get_browser 
b = get_browser() 

b.go("http://www.python.org/") 
b.showforms() 
0

Funkload to także doskonałe narzędzie do testowania aplikacji internetowej. Łączy webunit, aby obsługiwał emulację przeglądarki, a następnie udostępnia funkcje testowania funkcjonalnego i obciążenia.

11

Musiałem ostatnio zrobić to samo. Potrzebowałem tylko klas ze standardowej biblioteki. Oto fragment z mojego kodu:

from urllib import urlencode 
from urllib2 import urlopen, Request 

# encode my POST parameters for the login page 
login_qs = urlencode([("username",USERNAME), ("password",PASSWORD)]) 

# extract my session id by loading a page from the site 
set_cookie = urlopen(URL_BASE).headers.getheader("Set-Cookie") 
sess_id = set_cookie[set_cookie.index("=")+1:set_cookie.index(";")] 

# construct headers dictionary using the session id 
headers = {"Cookie": "session_id="+sess_id} 

# perform login and make sure it worked 
if "Announcements:" not in urlopen(Request(URL_BASE+"login",headers=headers), login_qs).read(): 
    print "Didn't log in properly" 
    exit(1) 

# here's the function I used after this for loading pages 
def download(page=""): 
    return urlopen(Request(URL_BASE+page, headers=headers)).read() 

# for example: 
print download(URL_BASE + "config") 
13

@ S.Lott, dziękuję. Twoja sugestia działała dla mnie, z pewnymi modyfikacjami. Oto jak to zrobiłem.

data = urllib.urlencode(params) 
url = host+page 
request = urllib2.Request(url, data, headers) 
response = urllib2.urlopen(request) 

cookies = CookieJar() 
cookies.extract_cookies(response,request) 

cookie_handler= urllib2.HTTPCookieProcessor(cookies) 
redirect_handler= HTTPRedirectHandler() 
opener = urllib2.build_opener(redirect_handler,cookie_handler) 

response = opener.open(request) 
15

Oto moje zdanie na ten temat.

#!/usr/bin/env python 

import urllib 
import urllib2 


class HttpBot: 
    """an HttpBot represents one browser session, with cookies.""" 
    def __init__(self): 
     cookie_handler= urllib2.HTTPCookieProcessor() 
     redirect_handler= urllib2.HTTPRedirectHandler() 
     self._opener = urllib2.build_opener(redirect_handler, cookie_handler) 

    def GET(self, url): 
     return self._opener.open(url).read() 

    def POST(self, url, parameters): 
     return self._opener.open(url, urllib.urlencode(parameters)).read() 


if __name__ == "__main__": 
    bot = HttpBot() 
    ignored_html = bot.POST('https://example.com/authenticator', {'passwd':'foo'}) 
    print bot.GET('https://example.com/interesting/content') 
    ignored_html = bot.POST('https://example.com/deauthenticator',{}) 
+0

Jest to jedyna odpowiedź, która w rzeczywistości sprawia, że ​​proces ten jest prosty. – EMI