可以看到,将我们文件的内容打印了出来
此外我们还可以禁止重定向,只需要指定allow_redirects=False即可
python import requests res = requests.get("http://www.taobao.com", allow_redirects=False) print(res.status_code) # 301 print(res.history) # []可以看到,当我们使用res1.text的时候,能够打印出cookie,但是使用res2.text,就打印不出cookie了,这是为什么?
当我们执行session.get('http://httpbin.org/cookies/set/sessioncookie/123456789')的时候,会返回一个cookie,这个cookie已经被保存在会话里了,因此当我们再次使用session(会话)发送请求的时候会自动将这个cookie带过去。但是当我们使用requests.get的时候,则是创建一个新会话。因此只能先拿到cookie,然后再显示的将cookie传过去,但如果是会话的话就不用了,因为会自动的将cookie保存起来
此外会话还可以为请求方法提供缺省数据
python import requests session = requests.Session() """ Session这个类里面,有很多的属性,比如headers,auth,cookies,proxies等等 但是没有在__init__中定义,即便如此我们仍然可以通过属性访问的方式来添加 """ session.headers.update({"User-Agent": "kubernetes"}) # 此时调用get方法的时候,会将headers带过去 res = session.get("http://www.baidu.com") print(res.request.headers) # {'User-Agent': 'kubernetes', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} # 但是如果我们在请求的方法中又传了相应的参数,那么请求方法中的参数,会覆盖会话当中的参数 res = session.get("http://www.baidu.com", headers={"User-Agent": "docker", "name": "satori"}) print(res.request.headers) """ {'User-Agent': 'docker', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'name': 'satori', 'Cookie': 'BAIDUID=B2A159333ED50D72BC07D66F1040A68E:FG=1; BIDUPSID=B2A159333ED50D72BC07D66F1040A68E; H_PS_PSSID=26525_1447_21090_29135_29238_28519_29099_29131_28832_29221_26350_29072; PSTM=1561642196; delPer=0; BDSVRTM=0; BD_HOME=0'} """ # 可以看到kubernetes被docker覆盖了,而且我们设置的name也出现了。最关键的是,居然还出现了cookie,这是为什么? # 因为在第一次访问百度的时候,返回给我们一个cookie,第二次访问的时候,使用的是同一个session,所以会将上一步得到的cookie带过去 res = session.get("http://www.baidu.com") print(res.request.headers) """ {'User-Agent': 'kubernetes', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': 'BAIDUID=AB0351E419827120EABABE13ECC4C9ED:FG=1; BIDUPSID=AB0351E419827120EABABE13ECC4C9ED; H_PS_PSSID=1422_21110_29135_29237_28519_29098_29131_28838_29220_22160; PSTM=1561642425; delPer=0; BDSVRTM=0; BD_HOME=0'} """ # 这里问题又来了,可以看到,我们第三次访问的时候,User-Agent又变回了kubernetes,而且name也没了,cookie还在。这是为什么? # 因为方法中的参数不会跨请求保持,我们在请求的时候所设置的参数,仅仅对那一次请求有效。如果之后不指定,那么请求还是会使用会话里面的,所以是这个结果。并且,由于Session类实现了__enter__和__exit__方法,所以还可以使用with语句
在任何时候,只要进行了类似于requests.get的调用,都在做两件主要的事情。第一,在构建一个Request对象,该对象被发送到某个服务器上请求或查询一些资源。第二,一旦requests得到一个从服务器返回的相应就会产生一个Response对象、该响应对象包含服务器返回的所有信息,也包含原来创建的Request对象。
python import requests session = requests.Session() # 先来看看session.request的源码 # 值得一提的是,requests.get、post等请求方法,都是调用的requests.request # 但是requests.requests实际上也是创建了一个session对象,调用session对象下的request方法,只不过这个session对象在这一次请求之后就没有了,因为我们没有保存 # 而session对象下也有get、post等方法,当然调用也是session.request。 # 因此无论是通过requests主模块、还是创建的session对象,其所调用的get、post、delete等请求方法,最终调用的都是session对象下的request方法 """ def request(self, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, proxies=None, hooks=None, stream=None, verify=None, cert=None, json=None): # Create the Request.创建一个Request对象 # 里面主要包装我们的一些参数 req = Request( method=method.upper(), url=url, headers=headers, files=files, data=data or {}, json=json, params=params or {}, auth=auth, cookies=cookies, hooks=hooks, ) # 准备的请求,后面会说 prep = self.prepare_request(req) proxies = proxies or {} settings = self.merge_environment_settings( prep.url, proxies, stream, verify, cert ) # Send the request. send_kwargs = { 'timeout': timeout, 'allow_redirects': allow_redirects, } send_kwargs.update(settings) # 发送请求,得到Response对象 resp = self.send(prep, **send_kwargs) return resp """ res = session.get("https://www.baidu.com") # 获取服务器返回的头部信息 print(res.headers) """ {'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'Keep-Alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Thu, 27 Jun 2019 14:07:13 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:23:55 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'} """ # 还可以获取发送给服务器的请求的头部 print(res.request.headers) # {'User-Agent': 'python-requests/2.19.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}当从api或者会话调用中收到一个Response对象时,request属性实际上使用了Prepared Request。因此在发送请求之前,我们可以对body、header做一些额外的处理
python import requests session = requests.Session() req = requests.Request("get", url="https://www.baidu.com") prepped = req.prepare() # 可以做一些额外的处理,这里处理请求头 prepped.headers["User-Agent"] = "satori" # 调用session的send方法,这个requests模块内部的session.request本质上也是这么做的,返回的就是Response对象 res = session.send(prepped) print(res.request.headers) # {'User-Agent': 'satori'} print(res.cookies.get_dict()) # {'BIDUPSID': '6A947E75D63F889E10C89D7E6A2870AA', 'PSTM': '1561645151', 'BD_NOT_HTTPS': '1'} print(res.url) # https://www.baidu.com/然而,上述代码会失去 Requests Session 对象的一些优势, 尤其session级别的状态,例如 cookie 就不会被应用到你的请求上去。要获取一个带有状态的PreparedRequest, 可以使用 Session.prepare_request 取代Request.prepare的调用.
只需要将prepped = req.prepare()换成prepped = session.prepare_request()即可
不过感觉不常用,至少我基本上没怎么用过
requests可以为HTTPS请求验证ssl证书,就像web浏览器一样。ssl验证默认是开启的,如果证书验证失败,那么requests会抛出一个SSLError,对于那些没有设置ssl的,如果验证失败那么可以在请求方法中加上verify=False,表示不验证
也可以为 verify 传入 CA_BUNDLE 文件的路径,或者包含可信任 CA 证书文件的文件夹路径
或者让其保持在会话中
s = requests.Session() s.verify = '证书路径' # 值得一提的是 # 如果 verify 设为文件夹路径,文件夹必须通过 OpenSSL 提供的 c_rehash 工具处理。也可以指定一个本地证书用作客户端证书,可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组:
requests.get('url', cert=('client.cert', 'client.key'))或者让其保持在会话中
s = requests.Session() s.cert = 'client.cert'如果指定了一个错误的证书,那么同样会引发一个SSLError
如果需要使用代理,可以通过为任意请求方法提供 proxies 参数来配置单个请求
python import requests proxies = { "http": "http://10.10.1.10:3128", "https": "http://10.10.1.10:1080", } requests.get("http://example.org", proxies=proxies)若你的代理需要使用HTTP Basic Auth,可以使用 http://user:password@host/ 语法:
python proxies = { "http": "http://user:pass@10.10.1.10:3128/", }要为某个特定的连接方式或者主机设置代理,使用 scheme://hostname 作为 key, 它会针对指定的主机和连接方式进行匹配。
python proxies = {'http://10.20.1.128': 'http://10.10.1.10:5323'}注意,代理 URL 必须包含连接方式。
除了基本的http代理,requests还支持socks代理。如果要使用的话,需要安装第三方库,pip install requests[socks]。
一般我们使用socks都是获取接口数据,在python中还有一个比较好用的模块,叫suds。
python from suds.client import Client client = Client(url="xxx") res = getattr(client.service, "func")(*params)但是在requests中,使用socks代理和http代理是一样的
python proxies = { 'http': 'socks5://user:pass@host:port', 'https': 'socks5://user:pass@host:port' }转载于:https://www.cnblogs.com/valorchang/p/11395565.html