2010-03-11 7 views
7

Quindi sto cercando in urllib3 perché ha il pool di connessioni ed è thread-safe (quindi le prestazioni sono migliori, specialmente per la scansione), ma la documentazione è ... per dirla come minimo. urllib2 ha build_opener così qualcosa di simile:Python urllib3 e come gestire il supporto dei cookie?

#!/usr/bin/python 
import cookielib, urllib2 
cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
r = opener.open("http://example.com/") 

Ma urllib3 non ha un metodo build_opener, quindi l'unico modo che ho capito finora è quello di mettere manualmente nell'intestazione:

#!/usr/bin/python 
import urllib3 
http_pool = urllib3.connection_from_url("http://example.com") 
myheaders = {'Cookie':'some cookie data'} 
r = http_pool.get_url("http://example.org/", headers=myheaders) 

Ma io sono sperando che ci sia un modo migliore e che uno di voi possa dirmi di cosa si tratta. Puoi anche taggare con "urllib3" per favore.

+0

@bigredbob, contrassegnati come hai chiesto. Ho esaminato le fonti di urllib3 e sembra che non abbia nessuno dei tweak and turn di urllib2, compresi gli oggetti 'Opener', quindi dubito che ci sia una bacchetta magica per te. Speriamo che maturi con il tempo, dato che è piuttosto acerbo fin d'ora! -) –

risposta

9

Hai ragione, non esiste un modo immediatamente migliore per farlo al momento. Sarei più che felice di accettare una patch se si dispone di un miglioramento congruente.

Una cosa da tenere a mente, il HTTPConnectionPool di urllib3 è inteso come un "pool di connessioni" per un host specifico, al contrario di un client con stato. In questo contesto, ha senso tenere traccia dei cookie al di fuori del pool effettivo.

  • shazow (l'autore di urllib3)
+0

Se sapessi come applicare la patch, mi piacerebbe molto, ma non sono così bravo. È bello sapere che non sto sbagliando almeno. – bigredbob

1

È necessario impostare 'Cookie' non 'Set-Cookie', 'Set-Cookie' impostato dal server Web.

E i cookie sono uno degli header, quindi non c'è niente di sbagliato nel farlo in quel modo.

+0

Sì, quello era un errore di battitura, ma la mia domanda è ancora valida, mi piacerebbe un modo migliore (ad esempio usando i built-in). – bigredbob

2

Non c'è un problema con più cookie?

Alcuni server restituiscono più intestazioni Set-Cookie, ma urllib3 memorizza le intestazioni in un dict e un ditt non consente più voci con la stessa chiave.

httplib2 ha un problema simile.

O forse no: si scopre che il metodo readheaders della classe HTTPMessage nel pacchetto httplib - che sia urllib3 e httplib2 uso - ha il seguente commento:

Se più campi di intestazione con il stesso nome si verificano, sono combinati in base alle regole di RFC 2616 sec 4.2:

Appending each subsequent field-value to the first, each separated 
    by a comma. The order in which header fields with the same field-name 
    are received is significant to the interpretation of the combined 
    field value. 

Quindi non intestazioni sono persi.

C'è, tuttavia, un problema se ci sono virgole all'interno di un valore di intestazione. Non ho ancora capito cosa sta succedendo qui, ma da skimming RFC 2616 ("Hypertext Transfer Protocol - HTTP/1.1") e RFC 2965 ("HTTP State Management Mechanism") ho l'impressione che tutte le virgole all'interno di un header il valore dovrebbe essere quotato

+0

RFC6265 dice che Set-Cookie deve essere speciale per gestire questo. httplib non lo sta facendo in python 2 ... vedi http://bugs.python.org/issue1660009 – reteptilian

2

È necessario utilizzare la libreria delle richieste. Usa urllib3 ma rende le cose come l'aggiunta di cookie banali.

https://github.com/kennethreitz/requests

import requests 
r1 = requests.get(url, cookies={'somename':'somevalue'}) 
print(r1.content) 
+0

Si suppone che aggiunga un cookie al mio browser? Se sì, quali sono alcuni motivi per cui non funzionerebbe? Ho provato questo sul mio sito web locale in esecuzione su server Apache, Windows 10, Python 2.75. –

1

è possibile utilizzare un codice come questo:

def getHtml(url): 
    http = urllib3.PoolManager() 
    r = http.request('GET', url, headers={'User-agent':'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36','Cookie':'cookie_name=cookie_value'}) 
    return r.data #HTML 

È necessario sostituire cookie_name e cookie_value

Problemi correlati