私は新しいPython Requestsライブラリを使用してhttpリクエストを作成します。サーバーからテキストとしてCookieを取得します。それをCookieを含むCookieJar
にするには?
私はこの質問に戸惑っています。要求ライブラリは、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を満たします。 2番目の要求は、Cookieをサーバーに送り返します。同じことが標準ライブラリのurllibモジュール cookielib にも当てはまります。 (2.xバージョンで現在利用可能なドキュメント)
リクエスト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/#session-objects から盗まれました)
コードの実行間でCookieをディスクに保持したい場合は、Cookie jarを直接使用して保存/ロードできます。さらに面倒ですが、それでもかなり簡単です:
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
これらの答えの多くは、ポイントを欠いていると思います。他のライブラリが内部でリクエストを使用していない場合があります。または、使用しているcookiejarを公開しません。時々私たちが持っているすべてはCookie文字列です。私の場合、pyVmomiから認証Cookieを借りようとしています。
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)
あなたを助けるために、私はモジュール全体を書きました。私の個人的なWebページとgoogleのcookieで試してみたので、うまくいくと思います。
Pythonで既存のcookielib CookieJarインスタンスにcookieを追加する方法?
私はここにセミクラッジを含む多くの非Pythonコードを持っているので、あなたの走行距離は変わるかもしれません。特に、想定される項目(ポート80など)では、以下の引数としての「request」はrequests.request型であり、「method」引数はすべて大文字でなければならないことに気付きました。私が助けてくれることを願っています!
注:明確にするためにコメントを追加する時間がないため、ソースを使用する必要があります。
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には、ロードメソッドと保存メソッドがあります。形式を見て、それがネイティブCookie形式と一致するかどうかを確認します。StringIOを使用して、CookieをCookie jarに直接ロードできる場合があります。また、リクエストが内部でurllib2を使用している場合、デフォルトのオープナーに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)
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)
overthinkの簡易バージョン、cookiejarを取得し、Python3でcookieを保持する方法について:
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は、 https://www.stackoverflow.com のCookieを取得しません。これは、wwwなしでサイトにリダイレクトされるためです。
このサイトを試してください: Voidspace article
長年にわたり、私はこの種のことを行うのにボイドスペースが非常に役立つことを発見しました。私が助けてくれたことを願っていますが、私は非常に劣等生です。ダウンロードファイルは「.py-」ファイルですが、コードは Voidspace Recipes でソースコード.pyとして入手できます。
dstanek answered のように、リクエストは自動的にレスポンスCookieをCookie jarに入れます。
ただし、Cookie
ヘッダーエントリを手動で指定した場合、リクエストはそれらのCookieをjarに入れません 。つまり、後続のリクエストには最初のCookieのセットはありませんが、今後は新しいCookieが含まれます。
リクエスト用の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 jarandCookie
ヘッダーを指定した場合、ヘッダーが優先されますが、Cookie jarは引き続き保持されます。今後のリクエスト。