2011-07-29 34 views
32

我正在使用新的Python請求庫來發出http請求。我從服務器獲取一個cookie作爲文本。我怎麼把它變成一個CookieJar與它的cookie?在CookieJar中放置一個`Cookie`

+1

我看到你的Python郵件列表消息,我在這裏看到你絕望的原因。 –

+1

我看不到它。最重要的答案是什麼如此糟糕/令人費解? – panzi

+1

最好的答案非常好,我被之前的答案迫切地解決了。 –

回答

40

我很困惑這個問題。請求庫將cookie放入jar中。

import requests 
import cookielib 


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

URL的第一個請求將填充jar。第二個請求會將cookies發送回服務器。標準庫的urllib模塊cookielib也是如此。 (doc目前可用於2.x版本)

+0

啊,不知道。謝謝。 –

+2

剛發佈的新版本(v0.6.0)允許您使用簡單字典將cookie附加到請求。 http://docs.python-requests.org/en/latest/user/quickstart/#cookies –

+0

謝謝!這讓我意識到,在webtest中,testapp.post(url)會將任何收到的cookie添加到testapps cookiejar中。 –

1

試試這個網站:Voidspace article

多年來,我發現voidspace是做這種東西非常有用的歲月。希望我能幫上忙,雖然我相當笨拙。儘管下載文件是一個「.py-」文件,但代碼可在Voidspace Recipes 處作爲源代碼.py。

+0

對於這麼簡單的任務真的太複雜了。我猜我唯一能做的就是等待'requests'來實現cookie處理。 –

+0

我是一名網絡程序員,但我主要參與發送cookie。因爲公司互聯網不允許程序化網絡潛水,所以我會在回家後進行修改。 –

+0

剛發佈的新版本(v0.6.0)允許您使用簡單字典將cookie附加到請求。 http://docs.python-requests.org/en/latest/user/quickstart/#cookies –

2

我正在嘗試做同樣的事情。這是我迄今爲止,並由於某種原因,它不是在標題中發送cookie。儘管如此,它可能會幫助你解決問題。

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

剛發佈的新版本(v0.6.0)允許您使用簡單字典將cookie附加到請求中。 http://docs.python-requests.org/en/latest/user/quickstart/#cookies –

+0

@Kenneth Reitz真棒,謝謝。 –

4

爲了幫助你,我寫了一個完整的模塊。我試着用我的個人網頁和谷歌的cookies,所以我會假設它的工作原理。

我得到的幫助來自How to add cookie to existing cookielib CookieJar instance in Python?

我在這裏包括半雜牌很多unpythonic代碼,所以你的里程可能會有所不同。按照你的意願調整它,特別是假設的項目(例如端口80),下面的「請求」作爲參數是requests.request類型,我意識到「方法」參數必須是全部大寫。希望我能幫忙!

注意:我沒有時間添加註釋以便澄清,因此您必須使用源代碼。

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 
+0

我有name =「undefined」,因爲我一直無法找出名字的位置。如果有人能指出哪裏,我會很樂意更新代碼。 –

+0

如果你有太多的cookies(我懷疑cookie的作用),請隨意使用yield而不是return。 –

+1

剛發佈的新版本(v0.6.0)允許您使用簡單字典將cookie附加到請求。 http://docs.python-requests.org/en/latest/user/quickstart/#cookies –

3

那麼cookielib.LWPCookieJar就有加載和保存方法。查看格式並查看它是否與原生cookie格式相匹配,您可以使用StringIO直接將cookie加載到cookie jar中。或者,如果請求使用的是引擎蓋下的urllib2,那麼您是否可以將cookie處理程序添加到默認的opener?

1

假設您已請求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) 
20

A請求Session也將接收和發送餅乾。

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/#session-objects被盜)

如果你想餅乾堅持在你的代碼的運行之間的磁盤,你可以直接使用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 
+2

我真的希望這個票被選爲最高票。選擇的最佳答案根本不起作用 - 2.3.0 – djsumdog

+0

拯救我的一天,完美的答案! – jesuscc29

0

由於dstanek answered,請求將自動把響應餅乾的餅乾罐爲您服務。
但是,如果您手動指定一個Cookie標題條目,請求不會將這些cookie放在一個jar中供您使用。這意味着後續的任何請求都將缺少您的初始Cookie,但將會有新的cookies出現。

如果確實需要手動爲請求創建cookie jar,請使用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罐一個Cookie頭,頭優先,但餅乾罐仍將維持將來的請求。