wake-up-neo.net

Ein "Cookie" in ein "CookieJar" setzen

Ich benutze die neue Python Requests-Bibliothek, um HTTP-Anfragen zu stellen. Ich erhalte einen Cookie vom Server als Text. Wie mache ich daraus eine CookieJar mit dem Cookie?

36
Ram Rachum

Ich bin durch diese Frage verwirrt. Die Anforderungsbibliothek fügt die Cookies für Sie in das Glas ein.

import requests
import cookielib


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

Die erste Anfrage an die URL füllt das Glas. Die zweite Anfrage sendet die Cookies zurück an den Server. Dasselbe gilt für das Urllib-Modul der Standardbibliothek cookielib . (aktuell verfügbares Dokument für die 2.x-Version)

44
dstanek

Eine Anfrage Session empfängt und sendet auch 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 oben aus http://www.python-requests.org/de/latest/user/advanced/#session-objects ) gestohlen

Wenn Sie möchten, dass Cookies zwischen den Code-Läufen auf der Festplatte verbleiben, können Sie ein Cookie-Glas direkt verwenden und speichern/laden. Umständlicher, aber immer noch ziemlich einfach:

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)

Dann schau in die Datei:

$ cat /tmp/cookies 
#LWP-Cookies-2.0
Set-Cookie3: sessioncookie=123456789; path="/"; domain="httpbin.org"; path_spec; discard; version=0
22
overthink

Um Ihnen zu helfen, habe ich ein ganzes Modul geschrieben. Ich habe es mit meiner persönlichen Webseite und den Cookies von Google ausprobiert. Ich gehe also davon aus, dass es funktioniert.

Ich habe Hilfe von Wie füge ich einen Cookie zu einer vorhandenen Cookielib-CookieJar-Instanz in Python hinzu?

Ich habe hier viel unpythonischen Code, einschließlich eines Semi-Kludges, so dass Ihre Laufleistung variieren kann. Passen Sie es nach Ihren Wünschen an. Insbesondere bei den angenommenen Elementen (z. B. Port 80) ist "request" als Argument unten vom Typ request.request, und ich habe festgestellt, dass das Argument "method" alle Großbuchstaben sein muss. Hoffe ich könnte helfen!

Hinweis: Ich hatte keine Zeit, Kommentare zur Klarstellung hinzuzufügen, daher müssen Sie die Quelle verwenden.

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
4

Nun, cookielib.LWPCookieJar hat Methoden zum Laden und Speichern. Schauen Sie sich das Format an und prüfen Sie, ob es mit dem ursprünglichen Cookie-Format übereinstimmt. Möglicherweise können Sie das Cookie mithilfe von StringIO direkt in ein Cookie-Glas laden. Wenn bei Anfragen urllib2 unter der Haube verwendet wird, können Sie dem Standardöffner nicht einen Cookie-Handler hinzufügen.

3
fuzzyman

Ich versuche das Gleiche zu tun. Das ist, was ich bis jetzt habe, und aus irgendeinem Grund werden die Cookies nicht in der Kopfzeile mitgeschickt. Es könnte Sie jedoch weit genug bewegen, um Ihr Problem zu lösen.

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)
2
Ken Cochrane

Ich denke, bei vielen dieser Antworten fehlt der Punkt. Manchmal verwendet diese andere Bibliothek keine Anfragen unter der Haube. Oder macht den verwendeten Cookie nicht frei. Manchmal sind wir haben nur die Cookie-Zeichenfolge. In meinem Fall versuche ich, den Auth Cookie von pyVmomi auszuleihen.

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)

Das gibt uns den folgenden 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)]>

Was können wir normal verwenden:

requests.get(..., cookies=cookie_jar)
2
Danny

Vereinfachte Version von überdenken Antwort, wie man ein Cookiejar bekommt und die Cookies in Python3 behält:

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

Um die Cookies zwischen Sitzungen beizubehalten, müssen Sie das Cookiejar in Sitzung speichern und wiederverwenden (die Variable s). Wenn Sie auf anderen Websites unterschiedliche Antworten für r1/r2/s erhalten, überprüfen Sie, ob eine Umleitung vorhanden ist. Als Beispiel wird r1/r2 kein Cookie für https://www.stackoverflow.com bekommen, da es ohne www auf die Seite umgeleitet wird.

1
Punnerud

Versuchen Sie diese Seite: Voidspace-Artikel

Im Laufe der Jahre habe ich festgestellt, dass Leerraum äußerst nützlich für diese Art von Sachen ist. Ich hoffe, ich habe geholfen, obwohl ich ein Dummkopf bin. Der Code ist unter Voidspace Recipes Als Quellcode .py verfügbar, obwohl die Downloaddatei eine ".py-" -Datei ist.

1

Angenommen, Sie haben url angefordert und als Antwort headers erhalten. Typ Typ von url ist String. Typ Typ von headers ist Liste.

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)
1
Utku Zihnioglu

Wenn dstanek geantwortet hat , werden Anfragen automatisch mit Antwort-Cookies in einem Keksdose abgelegt.
Wenn Sie jedoch manuell einen Cookie-Kopfeintrag angeben, setzen die Anforderungen wird nicht diese Cookies für Sie in ein Gefäß. Dies bedeutet, dass bei nachfolgenden Anfragen Ihre ursprünglichen Cookies fehlen, neue Cookies werden jedoch in der Zukunft angezeigt.

Wenn Sie einen Cookie-Behälter für Anforderungen manuell erstellen müssen, verwenden Sie requests.cookies.RequestsCookieJar . Falls sich ihr Beispielcode ändert:

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)

Beachten Sie, dass wenn Sie einen Cookie-Behälter und einen Cookie-Header angeben, der Header Vorrang hat, der Cookie-Behälter jedoch für zukünftige Anforderungen beibehalten wird.

0
Mr. Llama