2012-12-18 15 views
33

OK, więc używam tego dla bota reddit, ale chcę być w stanie wymyślić JAK zalogować się do dowolnej witryny. Jeśli to ma sens ...Zaloguj się do witryny za pomocą urllib2 - Python 2.7

Zdaję sobie sprawę, że różne strony internetowe używają różnych formularzy logowania itp. Jak więc dowiedzieć się, jak zoptymalizować go dla każdej witryny? Zakładam, że muszę poszukać czegoś w pliku html, ale nie mam pojęcia co.

NIE chcę używać Mechanize ani żadnej innej biblioteki (na tym polegają wszystkie inne odpowiedzi i tak naprawdę nie pomagam mi dowiedzieć się, co się dzieje), ponieważ chcę sam się dowiedzieć, jak dokładnie to wszystko działa.

Dokumentacja urllib2 naprawdę mi nie pomaga.

Dzięki.

Odpowiedz

45

Przedmówię to, mówiąc, że nie logowałem się w ten sposób przez jakiś czas, więc mógłbym przegapić niektóre z bardziej "akceptowanych" sposobów na zrobienie tego.

Nie jestem pewien, czy to jest to, co jesteś po, ale bez biblioteki jak mechanize lub solidniejszych ramach podobnego selenium, w podstawowym przypadku wystarczy spojrzeć na samej formie i odszukać inputs. Na przykład, patrząc na www.reddit.com, a następnie przeglądanie źródła świadczonych stronie znajdziesz tego formularza:

<form method="post" action="https://ssl.reddit.com/post/login" id="login_login-main" 
    class="login-form login-form-side"> 
    <input type="hidden" name="op" value="login-main" /> 
    <input name="user" placeholder="username" type="text" maxlength="20" tabindex="1" /> 
    <input name="passwd" placeholder="password" type="password" tabindex="1" /> 

    <div class="status"></div> 

    <div id="remember-me"> 
     <input type="checkbox" name="rem" id="rem-login-main" tabindex="1" /> 
     <label for="rem-login-main">remember me</label> 
     <a class="recover-password" href="/password">reset password</a> 
    </div> 

    <div class="submit"> 
     <button class="btn" type="submit" tabindex="1">login</button> 
    </div> 

    <div class="clear"></div> 
</form> 

Tutaj widzimy kilka input „S - op, user, passwd i rem. Zwróć także uwagę na parametr action - czyli adres URL, na który formularz zostanie opublikowany, a zatem będzie on naszym celem. Teraz ostatnim krokiem jest zapakowanie parametrów do ładunku i wysłanie go jako żądania POST do adresu URL . Również poniżej, tworzymy nową opener, dodać zdolność do obsługi ciasteczek i dodawanie nagłówków, a także, co daje nam nieco bardziej solidny otwieracz do wykonywania żądań):

import cookielib 
import urllib 
import urllib2 


# Store the cookies and create an opener that will hold them 
cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 

# Add our headers 
opener.addheaders = [('User-agent', 'RedditTesting')] 

# Install our opener (note that this changes the global opener to the one 
# we just made, but you can also just call opener.open() if you want) 
urllib2.install_opener(opener) 

# The action/ target from the form 
authentication_url = 'https://ssl.reddit.com/post/login' 

# Input parameters we are going to send 
payload = { 
    'op': 'login-main', 
    'user': '<username>', 
    'passwd': '<password>' 
    } 

# Use urllib to encode the payload 
data = urllib.urlencode(payload) 

# Build our Request object (supplying 'data' makes it a POST) 
req = urllib2.Request(authentication_url, data) 

# Make the request and read the response 
resp = urllib2.urlopen(req) 
contents = resp.read() 

pamiętać, że można to uzyskać znacznie bardziej skomplikowane - możesz to zrobić również za pomocą Gmaila, ale musisz pobrać parametry, które będą się zmieniać za każdym razem (np. parametr GALX). Ponownie, nie jestem pewien, czy to jest to, co chciałeś, ale mam nadzieję, że to pomaga.

+0

To jest/niesamowite /, dziękuję! Prawie dokładnie to, czego chciałem, teraz wiem, o czym również muszę przeczytać. Idealny! – tommo

+1

@tommo Nie ma problemu, mój przyjacielu - pamiętam, jak przechodziłam dokładnie tę samą linię pytań, kiedy próbowałem to uporządkować :) Powodzenia we wszystkim! – RocketDonkey

+0

Dzięki kolego :) Mam jeszcze jedno pytanie, na które nie mogę znaleźć odpowiedzi, jeśli nie masz nic przeciwko odpowiadaniu - Dlaczego użyłeś nawiasów [()] w "[(" User-agent ", "RedditTesting")] "? W dokumentacji ma ona tylko zwykłe nawiasy. – tommo