how - requests post python 3
Poniendo una `Cookie` en` CookieJar` (9)
Estoy usando la nueva biblioteca de Python Requests para hacer solicitudes http. Obtengo una cookie del servidor como texto. ¿Cómo puedo convertirlo en un CookieJar
con la cookie en él?
Bien cookielib.LWPCookieJar tiene métodos de carga y guardado en él. Mire el formato y vea si coincide con el formato de cookie nativo, puede cargar su cookie directamente en un tarro de cookies usando StringIO. De forma alternativa, si las solicitudes usan urllib2 bajo el capó, ¿no podría agregar un manejador de cookies al abridor predeterminado?
Como respondió dstanek , las solicitudes colocarán automáticamente cookies de respuesta en un contenedor de cookies para usted.
Sin embargo, si especifica manualmente una entrada de encabezado Cookie
, las solicitudes no colocarán esas cookies en un contenedor por usted. Esto significa que cualquier solicitud subsiguiente carecerá de su conjunto inicial de cookies, pero tendrá nuevas cookies en el futuro.
Si necesita crear manualmente un contenedor de cookies para las solicitudes, use docs.python-requests.org/en/latest/user/quickstart/#cookies . En caso de que su código de ejemplo cambie:
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)
Tenga en cuenta que si proporciona un cookie jar y un encabezado Cookie
, el encabezado tiene prioridad, pero el cookie jar se mantendrá para solicitudes futuras.
Creo que muchas de estas respuestas no tienen sentido. Algunas veces esa otra biblioteca no está usando solicitudes bajo el capó. O no expone el cookiejar que está usando. A veces todo lo que tenemos es la cadena de cookies. En mi caso, trato de pedir prestada la cookie de autenticación 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)
Lo cual nos da el siguiente cookie_jar
:
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 podemos usar como normal:
requests.get(..., cookies=cookie_jar)
Estoy confundido por esta pregunta. La biblioteca de solicitudes colocará las cookies en el contenedor por usted.
import requests
import cookielib
URL = ''...whatever...''
jar = cookielib.CookieJar()
r = requests.get(URL, cookies=jar)
r = requests.get(URL, cookies=jar)
La primera solicitud a la URL llenará el contenedor. La segunda solicitud enviará las cookies al servidor. Lo mismo ocurre con el módulo cookielib la biblioteca estándar cookielib . (doc actualmente disponible para la versión 2.x)
Estoy tratando de hacer lo mismo. Esto es lo que tengo hasta ahora, y por alguna razón no está enviando las cookies en el encabezado. Sin embargo, podría llegar lo suficientemente lejos como para resolver su problema.
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)
Para ayudarte, escribí un módulo completo. Lo probé con mi página web personal y las cookies de Google, así que supongo que funciona.
Obtuve ayuda de ¿Cómo agregar cookies a la instancia cookielib CookieJar existente en Python?
Tengo un montón de código antíptico aquí, incluido un semi-kludge, por lo que su kilometraje puede variar. Ajústalo como desees, especialmente con los elementos asumidos (como el puerto 80), la "solicitud" como argumento a continuación es de tipo request.request y me di cuenta de que el argumento "método" debe ser mayúsculas. Espero poder ayudar!
Nota: No he tenido tiempo de agregar comentarios para aclarar, así que tendrá que usar la fuente.
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
Pruebe este sitio: artículo Voidspace
Con el paso de los años, he descubierto que el espacio vacío es extremadamente útil para hacer este tipo de cosas. Espero haber ayudado, aunque soy bastante tonto. El código está disponible en Recetas de Voidspace como código fuente .py aunque el archivo de descarga es un archivo ".py".
Suponiendo que ha solicitado url
y obtuvo headers
como respuesta. Tipo tipo de url
es cadena. Tipo tipo de headers
es lista.
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)
Una Session
solicitudes también recibirá y enviará 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"}}''
(Código arriba robado de http://www.python-requests.org/en/latest/user/advanced/#session-objects )
Si desea que las cookies persistan en el disco entre ejecuciones de su código, puede usar directamente un contenedor de cookies y guardarlas / cargarlas. Más engorroso, pero aún bastante fácil:
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)
Luego mira en el archivo:
$ cat /tmp/cookies
#LWP-Cookies-2.0
Set-Cookie3: sessioncookie=123456789; path="/"; domain="httpbin.org"; path_spec; discard; version=0