Помещение `Cookie` в` CookieJar` - PullRequest
38 голосов
/ 30 июля 2011

Я использую новую библиотеку Python Requests для выполнения http-запросов.Я получаю куки с сервера в виде текста.Как мне превратить это в CookieJar с файлом cookie в нем?

Ответы [ 10 ]

45 голосов
/ 03 августа 2011

Я смущен этим вопросом. Библиотека запросов поместит куки в банку для вас.

import requests
import cookielib


URL = '...whatever...'
jar = cookielib.CookieJar()
r = requests.get(URL, cookies=jar)
r = requests.get(URL, cookies=jar)

Первый запрос к URL заполнит банку. Второй запрос отправит куки обратно на сервер. То же самое касается модуля urllib стандартной библиотеки cookielib . (документ доступен в версии 2.x)

24 голосов
/ 23 ноября 2013

Запросы Session также будут получать и отправлять файлы cookie.

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"}}'

(Код выше украден из http://www.python -requests.org / en / latest / user / advanced / # сеанс-objects )

Если вы хотите, чтобы файлы cookie сохранялись на диске между запусками вашего кода, вы можете напрямую использовать файл cookie и сохранять / загружать их.Более громоздким, но все же довольно простым:

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)

Затем посмотрите в файле:

$ cat /tmp/cookies 
#LWP-Cookies-2.0
Set-Cookie3: sessioncookie=123456789; path="/"; domain="httpbin.org"; path_spec; discard; version=0
4 голосов
/ 16 апреля 2018

Я думаю, что многие из этих ответов не имеют смысла.Иногда эта другая библиотека не использует запросы под капотом.Или не выставлять cookiejar, который он использует.Иногда все, что у нас есть , это строка cookie.В моем случае я пытаюсь позаимствовать файл cookie для аутентификации у 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)

, что дает нам следующее 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)]>

, которое мы можем использовать как обычно:

requests.get(..., cookies=cookie_jar)
4 голосов
/ 03 августа 2011

Чтобы помочь вам, я написал целый модуль.Я попробовал сделать это на своей личной веб-странице и в файлах cookie Google, поэтому предположил, что это работает.

Я получил помощь от Как добавить cookie в существующий экземпляр Cookielib CookieJar в Python?

У меня здесь много непифонического кода, включая полуклуб, поэтому ваш пробег может отличаться.Настройте его по своему желанию, особенно с предполагаемыми элементами (такими как порт 80), «запрос» в качестве аргумента ниже имеет тип запросов. Запрос, и я понял, что аргумент «метод» должен быть прописными.Надеюсь, что смогу помочь!

Примечание: у меня не было времени, чтобы добавить комментарии для разъяснения, поэтому вам придется использовать источник.

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
3 голосов
/ 03 августа 2011

Хорошо cookielib.LWPCookieJar содержит методы загрузки и сохранения.Посмотрите на формат и посмотрите, соответствует ли он собственному формату файлов cookie, возможно, вы сможете загрузить свои файлы cookie прямо в банку для файлов cookie, используя StringIO.В качестве альтернативы, если в запросах используется urllib2 изнутри, не могли бы вы добавить обработчик файлов cookie в средство открытия по умолчанию?

2 голосов
/ 03 августа 2011

Предполагается, что вы запросили url и получили headers в качестве ответа.Тип типа url является строкой.Тип headers является списком.

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)
2 голосов
/ 03 августа 2011

Я пытаюсь сделать то же самое. Это то, что я имею до сих пор, и по какой-то причине он не отправляет куки в шапке. Это может привести вас достаточно далеко, чтобы решить вашу проблему.

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)
1 голос
/ 04 марта 2019

Упрощенная версия ответа о том, как получить cookiejar и сохранить cookie в Python3:

import requests

s = requests.Session()

r1 = s.get('https://stackoverflow.com')
print("r1",r1.cookies) #Have cookie
print("s",s.cookies)  #Have cookie(jar)

r2 = s.get('https://stackoverflow.com') #The cookie from r1 is resend
print("r2",r2.cookies) #No cookie (could be a new one)
print("s",s.cookies)  #Keep the cookie(jar) from r1

Чтобы сохранить cookie между сеансами, которые необходимо сохранить иповторно используйте cookiejar в сеансе (переменная s ).Если вы получаете разные ответы между r1 / r2 / s на других сайтах, проверьте, есть ли перенаправление.Например, r1 / r2 не получит cookie для https://www.stackoverflow.com, потому что он перенаправлен на сайт без www.

1 голос
/ 23 мая 2017

Когда dstanek ответил , запросы автоматически поместят ответные файлы cookie в банку cookie.
Однако, если вы вручную укажете запись заголовка Cookie, запросы не будут положить эти печенья в банку для вас.Это означает, что во всех последующих запросах будет отсутствовать ваш начальный набор файлов cookie, но в будущем будут появляться все новые файлы cookie.

Если вам нужно вручную создать банку с cookie для запросов, используйте requests.cookies.RequestsCookieJar.В случае изменения их примера кода:

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)

Обратите внимание, что если вы предоставите заголовок cookie и a Cookie, заголовок будет иметь приоритет, но файл cookie будет сохранятьсядля будущих запросов.

1 голос
/ 01 августа 2011

Попробуйте этот сайт: Статья Voidspace

На протяжении многих лет я обнаружил, что пространство пустот чрезвычайно полезно для подобных вещей. Надеюсь, я помог, хотя я довольно тупица. Код доступен по адресу Рецепты Voidspace в виде исходного кода .py, хотя загружаемый файл представляет собой файл «.py-».

...