2012-12-18 11 views
33

Ok, quindi sto usando questo per un bot reddit, ma voglio essere in grado di capire come accedere a qualsiasi sito web. Se questo ha senso ....Accedi al sito web usando urllib2 - Python 2.7

Mi rendo conto che diversi siti Web utilizzano diversi moduli di accesso ecc. Quindi come faccio a capire come ottimizzarlo per ciascun sito web? Suppongo di dover cercare qualcosa nel file html ma non ho idea di cosa.

NON voglio usare Mechanize o qualsiasi altra libreria (su cui sono tutte le altre risposte qui e in realtà non mi aiutano a capire cosa sta succedendo), perché voglio imparare da solo come esattamente tutto funziona.

La documentazione di urllib2 non mi sta davvero aiutando.

Grazie.

risposta

45

Premetto che non ho fatto il login in questo modo per un po ', quindi potrei mancare alcuni dei modi più "accettati" per farlo.

io non sono sicuro se questo è quello che stai dopo, ma senza una libreria come mechanize o un quadro più solido come selenium, nel caso base basta guardare la forma stessa e cercare la inputs. Per esempio, guardando www.reddit.com, e quindi la visualizzazione del sorgente della pagina resa, troverete questo modulo:

<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> 

Qui vediamo un paio di input 's - op, user, passwd e rem. Inoltre, nota il parametro action, ovvero l'URL a cui verrà inviato il modulo e sarà quindi il nostro obiettivo. Quindi ora l'ultimo passaggio è il riempimento dei parametri in un carico utile e l'invio come richiesta POST all'URL action. Inoltre di seguito, creiamo un nuovo opener, aggiungere la possibilità di gestire i cookie e aggiungere intestazioni così, dandoci un apri un po 'più robusto per eseguire le richieste):

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() 

Si noti che questo può diventare molto più complicato - puoi farlo anche con GMail, ad esempio, ma devi inserire parametri che cambieranno ogni volta (come il parametro GALX). Ancora una volta, non sono sicuro se questo è quello che volevi, ma spero che aiuti.

+0

Questo è/fantastico /, grazie! Praticamente esattamente quello che volevo, ora so anche cosa devo leggere di più. Perfezionare! – tommo

+1

@tommo Nessun problema amico mio - Ricordo di aver attraversato esattamente la stessa riga di domande quando stavo cercando di riordinare quella cosa :) Buona fortuna a tutto! – RocketDonkey

+0

Grazie amico :) In realtà ho ancora una domanda a cui non riesco a trovare la risposta, se non ti dispiace rispondere - Perché hai usato le parentesi [()] in "[('User-agent', 'RedditTesting')] "? Nella documentazione ha solo parentesi normali. – tommo