關於requests的session方法無法保持cookie的問題。
2018年11月28日更新:
其實只要用cookies屬性的update方法更新cookie就行了。
比如:
cookie_dict = {"a":1}
s = requests.Session()
s.cookies.update(cookie_dict)
s.get(url)
...
下面的方法雖然也可以用,但相對比較繁瑣。
----------------------------以下是原來的內容---------------------------------
最近在做爬蟲的時候遇到了一個問題,在用requests的session方法保持cookie的時候發現requests不能保持手動構建的cookie。起初以為requests只能自動保持由伺服器返回的set-cookie語句中的cookie。後來查了很多資料,才終於明白。原來requests只能保持 cookiejar 型別的cookie,而我們手動構建的cookie是dict型別的。所以要把dict轉為 cookiejar型別,於是我又在網上查,在幾乎打算放棄的時候終於找到了一個把dict轉為cookiejar的方法,如下:
#將CookieJar轉為字典:
cookies = requests.utils.dict_from_cookiejar(r.cookies)
#將字典轉為CookieJar:
cookies = requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)
#其中cookie_dict是要轉換字典
轉換完之後就可以把它賦給cookies 並傳入到session中了:
s = requests.Session()
s.cookies = cookies
以上程式碼是我在下面這個網站上查到的,感謝這個部落格的作者!這篇文章上還介紹了一些官方文件中沒有提到的方法。
----------------------------以下是原文---------------------------------
原文地址:http://www.lihuai.net/program/python/1617.html
Python Requests庫:HTTP for Humans
時間: 2014/12/30 | 分類: Python | 作者: 李壞 | 瀏覽:287 | 搶沙發
Python標準庫中用來處理HTTP的模組是urllib2,不過其中的API太零碎了,requests是更簡單更人性化的第三方庫。
用pip下載:
pip install requests
或者git:
git clone git://github.com/kennethreitz/requests.git
傳送請求:
GET方法
>>> import requests
>>> r = requests.get('https://api.github.com/events')
POST方法:
>>> r = requests.post("http://httpbin.org/post")
也可以使用其它方法:
>>> r = requests.put("http://httpbin.org/put")
>>> r = requests.delete("http://httpbin.org/delete")
>>> r = requests.head("http://httpbin.org/get")
>>> r = requests.options("http://httpbin.org/get")
也可以將請求方法放在引數中:
>>> import requests
>>> req = requests.request('GET', 'http://httpbin.org/get')
傳遞引數或上傳檔案:
1.如果要將引數放在url中傳遞,使用params引數,可以是字典或者字串:
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("http://httpbin.org/get", params=payload)
>>> r.url
u'http://httpbin.org/get?key2=value2&key1=value1'
2.如果要將引數放在request body中傳遞,使用data引數,可以是字典,字串或者是類檔案物件。
使用字典時將傳送form-encoded data:
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
使用字串時將直接傳送資料:
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))
流上傳:
with open('massive-body', 'rb') as f:
requests.post('http://some.url/streamed', data=f)
Chunk-Encoded上傳:
def gen():
yield 'hi'
yield 'there'
requests.post('http://some.url/chunked', data=gen())
3.如果要上傳檔案,可以使用file引數傳送Multipart-encoded資料,file引數是{ ‘name’: file-like-objects}格式的字典 (or {‘name’?‘filename’, fileobj)}) :
>>> url = 'http://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": "<censored...binary...data>"
},
...
}
也可以明確設定filename, content_type and headers:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
>>> r = requests.post(url, files=files)
>>> print r.text
{
"args": {},
"data": "",
"files": {
"file": "1\t2\r\n"
},
"form": {},
"headers": {
"Content-Type": "multipart/form-data; boundary=e0f9ff1303b841498ae53a903f27e565",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.2.1 CPython/2.7.3 Windows/7",
},
"url": "http://httpbin.org/post"
}
一次性上傳多個檔案:
>>> url = 'http://httpbin.org/post'
>>> multiple_files = [('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
>>> r = requests.post(url, files=multiple_files)
>>> r.text
{
...
'files': {'images': 'data:image/png;base64,iVBORw ....'}
'Content-Type': 'multipart/form-data; boundary=3131623adb2043caaeb5538cc7aa0b3a',
...
}
設定Headers
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> headers = {'content-type': 'application/json'}
>>> r = requests.post(url, data=json.dumps(payload), headers=headers)
Response物件:
獲取unicode字串,會自動根據響應頭部的字元編碼(r.encoding)進行解碼,當然也可以自己設定r.encoding:
>>> r = requests.get('https://github.com/timeline.json')
>>> r.text
u'{"message":"Hello there, wayfaring stranger...
獲取bytes字串,會自動解碼gzip和deflate資料:
>>> r.content
'{"message":"Hello there, wayfaring stranger. ..
要儲存web圖片,可以:
>>> from PIL import Image
>>> from StringIO import StringIO
>>> i = Image.open(StringIO(r.content))
可以解碼json物件:
>>> r.json()
{u'documentation_url': u'https://developer...
返回raw response,需要在requests請求中將stream設為True:
>>> r = requests.get('https://github.com/timeline.json', stream=True)
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
>>> r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
如果不想一次性處理全部的資料,可以:
tarball_url = 'https://github.com/kennethreitz/requests/tarball/master'
r = requests.get(tarball_url, stream=True)
if int(r.headers['content-length']) < TOO_LONG:
content = r.content
...
也可以迭代的處理資料:
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size):
fd.write(chunk)
或者:
import json
import requests
r = requests.get('http://httpbin.org/stream/20', stream=True)
for line in r.iter_lines():
# filter out keep-alive new lines
if line:
print(json.loads(line))
獲取響應程式碼:
>>> r = requests.get('http://httpbin.org/get')
>>> r.status_code
200
獲取響應headers:
>>> r.headers
{
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json'
}
獲取傳送的headers
>>> r.request.headers
{'Accept-Encoding': 'identity, deflate, compress, gzip',
'Accept': '*/*', 'User-Agent': 'python-requests/1.2.0'}
Cookie
獲取cookie,返回CookieJar物件:
>>> url = 'http://www.baidu.com'
>>> r = requests.get(url)
>>> r.cookies
將CookieJar轉為字典:
>>> requests.utils.dict_from_cookiejar(r.cookies)
{'BAIDUID': '84722199DF8EDC372D549EC56CA1A0E2:FG=1', 'BD_HOME': '0', 'BDSVRTM': '0'}
將字典轉為CookieJar:
requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)
上傳自己設定的cookie,使用cookies引數,可以是字典或者CookieJar物件:
>>> url = 'http://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')
>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'
如果需要在會話中保留cookie,需要用到後面要說的Session。
Redirection and History
可以用history屬性來追蹤redirection
>>> r = requests.get('http://github.com')
>>> r.url
'https://github.com/'
>>> r.status_code
200
>>> r.history
[<Response [301]>]
Session
要在會話中保留狀態,可以使用request.Session()。
Session可以使用get,post等方法,Session物件在請求時允許你保留一定的引數和自動設定cookie
s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') #cookie保留在s中
r = s.get("http://httpbin.org/cookies") #再次訪問時會保留cookie
print(r.text)
# '{"cookies": {"sessioncookie": "123456789"}}'
也可以自己設定headers,cookies:
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'}) # 'x-test' and 'x-test2' 都會被髮送
預設Request
可以在傳送request前做些額外的設定
from requests import Request, Session
s = Session()
req = Request('GET', url,
data=data,
headers=header
)
prepped = req.prepare()
# do something with prepped.body
# do something with prepped.headers
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.status_code)
驗證
Basic Authentication
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
因為HTTP Basic Auth很常用,所以也可以直接驗證:
>>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
<Response [200]>
Digest Authentication
>>> from requests.auth import HTTPDigestAuth
>>> url = 'http://httpbin.org/digest-auth/auth/user/pass'
>>> requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
<Response [200]>
OAuth 1 Authentication
>>> import requests
>>> from requests_oauthlib import OAuth1
>>> url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
>>> auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET',
'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
>>> requests.get(url, auth=auth)
<Response [200]>
也可以使用自己寫的驗證類。比如某個web服務接受將X-Pizza報頭設定成密碼的驗證,可以這樣寫驗證類:
from requests.auth import AuthBase
class PizzaAuth(AuthBase):
"""Attaches HTTP Pizza Authentication to the given Request object."""
def __init__(self, username):
# setup any auth-related data here
self.username = username
def __call__(self, r):
# modify and return the request
r.headers['X-Pizza'] = self.username
return r
使用:
>>> requests.get('http://pizzabin.org/admin', auth=PizzaAuth('kenneth'))
<Response [200]>
SSL證照驗證
檢查主機的ssl證照:
>>> requests.get('https://kennethreitz.com', verify=True)
raise ConnectionError(e)
ConnectionError: HTTPSConnectionPool(host='kennethreitz.com', port=443): Max retries exceeded with url: / (Caused by <class 'socket.error'>: [Errno 10061] )
github是有的:
>>> requests.get('https://github.com', verify=True)
<Response [200]>
如果你設定驗證設定為False,也可以忽略驗證SSL證照。
可以讀取驗證檔案:
>>> requests.get('https://kennethreitz.com', cert=('/path/server.crt', '/path/key'))
代理
使用代理:
import requests
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
requests.get("http://example.org", proxies=proxies)
可以設定環境變數:
$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="http://10.10.1.10:1080"
$ python
>>> import requests
>>> requests.get("http://example.org")
如果代理需要驗證:
proxies = {
"http": "http://user:pass@10.10.1.10:3128/",
}
標籤: python學習
相關文章
- 關於Session和CookieSessionCookie
- 關於Cookie、session和Web StorageCookieSessionWeb
- 關於docker無法訪問倉庫的映象代理問題Docker
- 禁用 COOKIE 後如何訪問 SESSION 問題CookieSession
- python requests模組session的使用建議及整個會話中的所有cookie的方法PythonSession會話Cookie
- 6.7 版本 Cookie 跟 Session 存入問題CookieSession
- 關於 PHP Session ID 改變的問題解決PHPSession
- 關於Oath2.0Startup類無法啟動的問題
- 解決requests庫中session.verify引數失效的問題Session
- 使用requests庫解決Session物件設定超時的問題Session物件
- session和cookie關係SessionCookie
- Cookie與Session 關係CookieSession
- 關於Quartus的start按鈕灰色無法下載的問題的解決
- 關於網路硬體配置出現問題,無法上網問題的解決
- 爬蟲 | 處理cookie的基本方法——session爬蟲CookieSession
- 理解Cookie和Session機制,及其安全問題CookieSession
- 記錄springboot專案裡關於session的一個問題(session監聽器失效)Spring BootSession
- win10無法正常關機的最佳解決方法_如何解決win10無法正常關機的問題Win10
- 關於XAMPP中Apache和Mysql因埠占用無法啟動的問題ApacheMySql
- cookie與session的使用CookieSession
- 關於Centos7中Vscode無響應的問題及解決方法CentOSVSCode
- 關於Linux下Texlive無法找到已安裝字型的問題與解決Linux
- 獲取的 Cookie 為什麼無法用於爬蟲Cookie爬蟲
- 理解cookie、session、localStorage、sessionStorage的關係與區別CookieSession
- http中session和cookie的區別和關係HTTPSessionCookie
- 前後端頁面分離導致session無法正常獲取的問題後端Session
- requests庫中的Cookie處理Cookie
- IDEA中Lombok無法生效的問題及解決方法IdeaLombok
- goland中npm無法使用的問題及解決方法GoLandNPM
- 關於canonmx538無線連線的問題
- 關於Cookie的那些事Cookie
- Springboot中登入後關於cookie和session攔截案例Spring BootCookieSession
- cookie和session的區別CookieSession
- 對session和cookie的理解SessionCookie
- Tomcat 中的 Session 和 CookieTomcatSessionCookie
- session與cookie的區別SessionCookie
- 關於無法用 https 登入 SAP ABAP Netweaver 系統的問題和解決方案HTTP
- cookie sessionCookieSession
- cookie & sessionCookieSession