urllib3 Python et comment gérer le support des cookies?
Question
Je suis à la recherche dans urllib3 parce qu'il a mise en commun de connexion et est thread-safe ( si la performance est meilleure, surtout pour l'exploration), mais la documentation est ... minimale pour dire le moins. urllib2 a build_opener donc quelque chose comme:
#!/usr/bin/python
import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")
Mais urllib3 n'a pas de méthode de build_opener, la seule façon que je l'ai compris est jusqu'à présent le mettre manuellement dans l'en-tête:
#!/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)
Mais j'espère qu'il ya une meilleure façon et que l'un d'entre vous peut me dire ce qu'il est. peut aussi quelqu'un étiqueter avec « urllib3 » s'il vous plaît.
La solution
Vous avez raison, il n'y a pas immédiatement une meilleure façon de le faire en ce moment. Je serais plus qu'heureux d'accepter un patch si vous avez une amélioration congruents.
Une chose à garder à l'esprit, la HTTPConnectionPool de urllib3 est destiné à être un « pool de connexions » à un hôte spécifique, par opposition à un client stateful. Dans ce contexte, il est logique de garder le suivi des cookies en dehors de la piscine réelle.
- shazow (l'auteur de urllib3)
Autres conseils
est-il pas un problème avec plusieurs cookies?
Certains serveurs renvoient plusieurs têtes Set-Cookie, mais urllib3 stocke les en-têtes dans un dict et un dict ne permet pas d'entrées multiples avec la même clé.
httplib2 a un problème similaire.
Ou peut-être pas: il se trouve que la méthode readheaders de la classe HttpMessage dans le paquet httplib - tous deux urllib3 et httplib2 utilisation - a le commentaire suivant:
Si plusieurs champs d'en-tête avec le même nom se produisent, elles sont combinées selon les règles dans la RFC 2616 4.2 sec:
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.
Donc, pas en-têtes sont perdus.
Il y a, cependant, un problème s'il y a des virgules, une valeur d'en-tête. Je ne l'ai pas encore compris ce qui se passe ici, mais de l'écrémage RFC 2616 ( « Hypertext Transfer Protocol - HTTP / 1.1 ») et RFC 2965 ( « mécanisme de gestion HTTP Etat ») J'ai l'impression que les virgules dans un en-tête valeur sont censés être cité.
Vous devez définir 'Cookie'
pas 'Set-Cookie'
, 'Set-Cookie'
configurée par le serveur web.
Les cookies sont l'un des en-têtes, de sorte que son rien de mal à faire de cette façon.
Vous devez utiliser la bibliothèque de demandes. Il utilise urllib3 mais fait des choses comme ajouter des cookies trivial.
https://github.com/kennethreitz/requests
import requests
r1 = requests.get(url, cookies={'somename':'somevalue'})
print(r1.content)
Vous pouvez utiliser un code comme ceci:
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
Vous devez remplacer cookie_name et cookie_value