J'utilise la nouvelle bibliothèque Python Requests pour effectuer des requêtes http. J'obtiens un cookie du serveur sous forme de texte. Comment transformer cela en une CookieJar
avec le cookie?
Je suis confus par cette question. La bibliothèque de demandes mettra les cookies dans le pot pour vous.
import requests
import cookielib
URL = '...whatever...'
jar = cookielib.CookieJar()
r = requests.get(URL, cookies=jar)
r = requests.get(URL, cookies=jar)
La première demande à l'URL remplira le fichier. La deuxième demande renverra les cookies au serveur. Il en va de même pour le module urllib de la bibliothèque standard cookielib . (doc actuellement disponible pour la version 2.x)
Une demande Session
recevra et enverra également des cookies.
s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
print(r.text)
# '{"cookies": {"sessioncookie": "123456789"}}'
(Code ci-dessus volé à http://www.python-requests.org/en/latest/user/advanced/#session-objects )
Si vous souhaitez que les cookies persistent sur le disque entre les exécutions de votre code, vous pouvez directement utiliser un fichier jar de cookie et les enregistrer/charger. Plus lourd, mais toujours assez facile:
import requests
import cookielib
cookie_file = '/tmp/cookies'
cj = cookielib.LWPCookieJar(cookie_file)
# Load existing cookies (file might not yet exist)
try:
cj.load()
except:
pass
s = requests.Session()
s.cookies = cj
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
# Save cookies to disk, even session cookies
cj.save(ignore_discard=True)
Puis regardez dans le fichier:
$ cat /tmp/cookies
#LWP-Cookies-2.0
Set-Cookie3: sessioncookie=123456789; path="/"; domain="httpbin.org"; path_spec; discard; version=0
Pour vous aider, j'ai écrit un module entier. Je l'ai essayé avec ma page Web personnelle et les cookies de Google. Je suppose donc que cela fonctionne.
J'ai obtenu de l'aide de Comment ajouter un cookie à une instance cookielib CookieJar existante en Python?
J'ai beaucoup de code non polythonique ici, y compris un semi-kludge, donc votre kilométrage peut varier. Ajustez-le à votre guise, en particulier avec les éléments supposés (tels que le port 80), la "requête" en tant qu'argument ci-dessous est du type requests.request et je me suis rendu compte que l'argument "méthode" devait être en majuscules. J'espère pouvoir aider!
Note: Je n'ai pas eu le temps d'ajouter des commentaires pour des éclaircissements, vous devrez donc utiliser la source.
import Cookie,cookielib,requests,datetime,time #had this out but realized later I needed it when I continued testing
def time_to_Tuple(time_string):
wday = {'Mon':0,'Tue':1,'Wed':2,'Thu':3,'Fri':4,'Sat':5,'Sun':6}
mon = {'Jan':1,'Feb':2,'Mar':3,'Apr':4,'May':5,'Jun':6,'Jul':7,'Aug':8,'Sep':9,'Oct':10,'Nov':11,'Dec':12}
info = time_string.split(' ')
info = [i.strip() for i in info if type(i)==str]
month = None
for i in info:
if '-' in i:
tmp = i.split('-')
for m in tmp:
try:
tmp2 = int(m)
if tmp2<31:
mday = tmp2
Elif tmp2 > 2000:
year = tmp2
except:
for key in mon:
if m.lower() in key.lower():
month = mon[key]
Elif ':' in i:
tmp = i.split(':')
if len(tmp)==2:
hour = int(tmp[0])
minute = int(tmp[1])
if len(tmp)==3:
hour = int(tmp[0])
minute = int(tmp[1])
second = int(tmp[2])
else:
for item in wday:
if ((i.lower() in item.lower()) or (item.lower() in i.lower())):
day = wday[item]
if month is None:
for item in mon:
if ((i.lower() in item.lower()) or (item.lower() in i.lower())):
month = mon[item]
return year,month,mday,hour,minute,second
def timefrom(year,month,mday,hour,minute,second):
time_now = time.gmtime()
datetime_now = datetime.datetime(time_now.tm_year,time_now.tm_mon,
time_now.tm_mday,time_now.tm_hour,
time_now.tm_min,time_now.tm_sec)
then = datetime.datetime(year,month,mday,hour,minute,second)
return (datetime_now-then).total_seconds()
def timeto(year,month,mday,hour,minute,second):
return -1*timefrom(year,month,mday,hour,minute,second)
##['comment', 'domain', 'secure', 'expires', 'max-age', 'version', 'path', 'httponly']
def parse_request(request):
headers = request.headers
cookieinfo = headers['set-cookie'].split(';')
name = 'Undefined'
port=80
port_specified=True
c = Cookie.SmartCookie(headers['set-cookie'])
cj = cookielib.CookieJar()
for m in c.values():
value = m.coded_value
domain = m['domain']
expires = m['expires']
if type(expires) == str:
tmp = time_to_Tuple(expires)
expires = timeto(tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5])
max_age=m['max-age']
version = m['version']
if version == '':
version = 0
path = m['path']
httponly = m['httponly']
if httponly == '':
if 'httponly' in headers['set-cookie'].lower():
httponly = True
else:
httponly = False
secure = m['secure']
comment=m['comment']
port = 80
port_specified=False
domain_specified=True
domain_initial_dot = domain.startswith('.')
path_specified=True
discard = True
comment_url=None
rest={'HttpOnly':httponly}
rfc2109=False
ck = cookielib.Cookie(version,name,value,port,port_specified,domain,
domain_specified,domain_initial_dot,path,path_specified,
secure,expires,discard,comment,comment_url,rest,rfc2109)
cj.set_cookie(ck)
return cj
Cookielib.LWPCookieJar contient des méthodes de chargement et de sauvegarde. Regardez le format et voyez s'il correspond au format de cookie natif, vous pourrez peut-être charger votre cookie directement dans un fichier jar à l'aide de StringIO. Sinon, si les demandes utilisent urllib2 sous le capot, ne pouvez-vous pas ajouter un gestionnaire de cookies à l'ouvre-porte par défaut?
J'essaie de faire la même chose. C’est ce que j’ai fait jusqu’à présent et, pour une raison quelconque, les cookies ne sont pas envoyés dans l’entête. Cependant, cela pourrait vous amener assez loin pour résoudre votre problème.
import requests
import cookielib
import logging
log = logging.getLogger(__name__)
def auth(auth_url, cookies):
cj = cookielib.CookieJar()
for x in cookies:
if len(cookies[x]) > 0:
ck = cookielib.Cookie(version=1, name=x, value=cookies[x],
port=None, port_specified=False, domain='.example.com',
domain_specified=True,
domain_initial_dot=True, path='/',
path_specified=True, secure=False,
expires=None, discard=True,
comment=None, comment_url=None,
rest=None, rfc2109=True)
log.info(ck)
cj.set_cookie(ck)
log.info("cookies = %s " % cj)
response = requests.get(auth_url, cookies=cj)
log.info("response %s \n" % response)
log.info("response.headers %s \n" % response.headers)
log.info("response.content %s \n" % response.content)
Je pense que beaucoup de ces réponses manquent le point. Parfois, cette autre bibliothèque n'utilise pas les requêtes sous le capot. Ou n'expose pas le cookiejar qu'il utilise. Parfois tout ce que nous avons est la chaîne de cookie. Dans mon cas, j'essaie d'emprunter le cookie d'authentification de pyVmomi.
import requests
import http.cookies
raw_cookie_line = 'foo="a secret value"; Path=/; HttpOnly; Secure; '
simple_cookie = http.cookies.SimpleCookie(raw_cookie_line)
cookie_jar = requests.cookies.RequestsCookieJar()
cookie_jar.update(simple_cookie)
Ce qui nous donne le cookie_jar
suivant:
In [5]: cookie_jar
Out[5]: <RequestsCookieJar[Cookie(version=0, name='foo', value='a secret value', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=True, expires=None, discard=False, comment='', comment_url=False, rest={'HttpOnly': True}, rfc2109=False)]>
Que nous pouvons utiliser comme d'habitude:
requests.get(..., cookies=cookie_jar)
Essayez ce site: Article sur l'espace vide
Au fil des années, j'ai trouvé l'espace vide extrêmement utile pour ce type de travail. J'espère que j'ai aidé, bien que je sois un cancre. Le code est disponible sur Recettes de l'espace vide En tant que code source .py bien que le fichier de téléchargement soit un fichier ".py-".
En supposant que vous avez demandé url
et que vous ayez headers
comme réponse. Le type de type url
est une chaîne. Le type type de headers
est list.
import urllib2
import cookielib
class dummyResponse:
def __init__(self,headers):
self.headers=headers
def info(self):
return dummyInfo(self.headers)
class dummyInfo:
def __init__(self,headers):
self.headers=headers
def getheaders(self,key):
#Headers are in the form: 'Set-Cookie: key=val\r\n'. We want 'key=val'
newMatches=[]
for header in self.headers:
if header.lower().startswith(key.lower()):
clearHeader=header[len(key)+1:].strip()
newMatches.append(clearHeader)
return newMatches
req=urllib2.Request(url)
resp=dummyResponse(headers)
jar=cookielib.CookieJar()
jar.extract_cookies(resp, req)
Lorsque dstanek a répondu , les demandes placent automatiquement les cookies de réponse dans un pot de cookies pour vous.
Cependant, si vous spécifiez manuellement une entrée d'en-tête Cookie
, les requêtes ne le seront pas mettent ces cookies dans un fichier jar pour vous. Cela signifie que toutes les demandes ultérieures manqueront de votre jeu initial de cookies, mais que de nouveaux cookies seront envoyés.
Si vous devez créer manuellement un cookie pour les demandes, utilisez requests.cookies.RequestsCookieJar
. Dans le cas où leur exemple de code change:
jar = requests.cookies.RequestsCookieJar()
jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
url = 'http://httpbin.org/cookies'
r = requests.get(url, cookies=jar)
Notez que si vous fournissez un cookie et un en-tête Cookie
, l'en-tête est prioritaire, mais le cookie sera toujours conservé pour les demandes futures.