1.3Requests

Requests 基本使用

python发送请求时,可以用requests模块,这个模块不是内置模块
需要安装 pip install requests

Requests库的七个主要方法:

方法 描述
requests.request() 构造一个请求,支撑一下各方法的基础方法
requests.get() 获取HTML网页的主要方法,对应HTTP的GET
requests.head() 获取HTML网页头的信息方法,对应HTTP的HEAD
requests.post() 向HTML网页提交POST请求方法,对应HTTP的POST
requests.put() 向HTML网页提交PUT请求的方法,对应HTTP的RUT
requests.patch() 向HTML网页提交局部修改请求,对应于HTTP的PATCH
requests.delete() 向HTML页面提交删除请求,对应HTTP的DELETE

get() 方法

requests.get(url, params=None, **kwargs)
url : 拟获取页面的url链接
params : url中的额外参数,字典或字节流格式,可选
**kwargs:控制访问参数,共12个

带参数

方式一

ret = requests.get("http://httpbin.org/get?name=leti&age=23")

方式二(建议使用,中文会自动转码)

ret=requests.get('http://0.0.0.0:8001/',params={'name':"美女",'age':18})
print(ret.text)

headers

ret = requests.get('http://0.0.0.0:8001/?name=%E7%BE%8E%E5%A5%B3',
            headers={
            # 标志,什么东西发出的请求,浏览器信息,django框架,从哪取?(meta)
            'User-Agent': 'request',
            # 上一个页面的地址,图片防盗链
            'Referer': 'xxx'
                   })
print(ret)

图片防盗链:如果图片的referer不是我自己的网站,就直接禁止掉

带 cookie,随机字符串(用户信息:也代表session),不管后台用的 token 认证,还是 session认证

第一种方式

ret = requests.get('http://0.0.0.0:8001/?name=%E7%BE%8E%E5%A5%B3',
                   headers={
                       'cookie': 'key3=value;key2=value',
                   })

第二种方式

ret = requests.get('http://0.0.0.0:8001/?name=%E7%BE%8E%E5%A5%B3',
                    cookies={"islogin":"xxx"})

发送 post 请求

post 请求(注册,登陆)携带数据(body)
data: urlencoded 编码

ret=requests.post('http://0.0.0.0:8001/',data={'name':"kai",'age':18})

json: json 编码

import json
data=json.dumps({'name':"kai",'age':18})
ret=requests.post('http://0.0.0.0:8001/',json=data)

注意:编码格式是请求头中带的,所以我可以手动修改,在 headers 中改

session 对象

session=requests.session()
#跟 requests.get/post 用起来完全一样,但是它处理了 cookie
#假设是一个登陆,并且成功
session.post()
#再向该网站发请求,就是登陆状态,不需要手动携带 cookie
session.get("地址")

Requests 对象的属性

属性 描述
r.status_code HTTP请求的返回状态,200表示成功
r.text HTTP响应内容的字符串形式,即:url对应的页面内容
r.encoding 从HTTP header中猜测的响应内容编码方式
r.apparent_encoding 从内容中分析出的响应内容编码方式(备选编码方式)
r.content HTTP响应内容的二进制形式
r.url 当次请求的地址
r.headers 响应头
r.cookies 服务端返回的 cookie
r.cookies.get_dict() 转成字典
r.history 如果有重定向,放到一个列表中

response.iter_content() # 视频,图片迭代取值

with open("a.mp4",'wb') as f:
    for line in response.iter_content():
        f.write(line)

乱码问题

import requests
response = requests.get("https://www.baidu.com")
print(response.status_code)  # 打印状态码
print(response.text)  #打印文本
print(response.cookies)  # 打印cookie信息
print(response.content)  #以字节流形式打印
print(response.content.decode("utf-8"))

我们可以看出 response 使用起来确实非常方便,这里有个问题需要注意一下: 很多情况下的网站如果直接 response.text 会出现乱码的问题,所以这个使用 response.content 这样返回的数据格式其实是二进制格式,然后通过 decode() 转换为 utf-8,这样就解决了通过 response.text 直接返回显示乱码的问题。
decode 的作用是将二进制数据解码成 unicode 编码,如 str1.decode('utf-8'),表示将 utf-8 的编码字符串解码成unicode编码。
简单的来说:decode就是把二进制数据(bytes)转化成人看的懂得英文或者汉字(decode用的比较多)
encode 的作用是将 unicode 编码的字符串编码成二进制数据,如str2.encode('utf-8'),表示将unicode 编码的字符串编码成 utf-8
请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当你访问 response.text 之时,Requests 会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用 response.encoding 属性来改变它。如:

response =requests.get("http://www.baidu.com")
response.encoding="utf-8"

response.apparent_encoding #当前页面的编码

r = res.apparent_encoding

不管是通过response.content.decode("utf-8)的方式还是通过response.encoding="utf-8"的方式都可以避免乱码的问题发生

解析 json

返回数据,有可能是 json 格式,有可能是 html 格式

> import requests
> import json
> response = requests.get("http://httpbin.org/get")
> print(type(response.text))
> print(response.json())
> print(json.loads(response.text))
> print(type(response.json()))

从结果可以看出 requests 里面集成的 json 其实就是执行了 json.loads() 方法,两者的结果是一样的

使用代理

正向代理
django 如何拿到客户端 ip 地址 META.get("REMOTE_ADDR")
使用代理有什么用

ret=requests.get('http://0.0.0.0:8001/',proxies={'http':'地址'})
print(ret.text)
import requests
ret=requests.get('https://www.cnblogs.com/',proxies={'http':'222.85.28.130:40505'})

http 请求头中:X-Forwarded-For:代理的过程

Post 上传文件

爬虫用的比较少,后台写服务

file={'myfile':open("1.txt",'rb')}
ret=requests.post('http://0.0.0.0:8001/',files=file)
print(ret.content)

上传图片

后端给出接口,上传阿里云后拿到阿里云图片链接

def post_img(self, img_name):
    '''
    图片上传阿里云
    :param img_name: 上传图片的路劲/名称
    :return: 图片链接
    '''
    url = 'http://xxx.xxx.xxx.xxx/upload'
    img_file = {'file': (img_name, open(img_name, 'rb'), 'image/jpg')}
    resp = requests.post(url, files=img_file).json()
    img_map_link = resp['data']['url']
    result_post = resp['succeeded']
    return img_map_link

Form Data

AJAX Post请求中常用的两种传参数的形式:form data 和 request payload
get请求的时候,我们的参数直接反映在url里面,形式为key1=value1&key2=value2形式,比如:
http://news.baidu.com/ns?word=NBA&tn=news&from=news&cl=2&rn=20&ct=1
如果是post请求,那么表单参数是在请求体中,也是以key1=value1&key2=value2的形式在请求体中
这里要注意post请求的Content-Type为application/x-www-form-urlencoded(默认的),参数是在请求体中,即上面请求中的Form Data

Request payload

如果使用原生AJAX POST请求的话,请求的 Content-Type为application/json;charset=UTF-8,而请求表单参数在Request Payload中
上传 payload 数据格式请求
注意: payload 数据要带上 []

def payload(self):  
    return [{
        'accountId': "66666777",
        'accountName': "黑兔",
            }]

def post_payload_data(self):
    import json
    resp = requests.post(url, data=json.dumps(self.payload(), ensure_ascii=False).encode(), headers=self.headers, verify=False)
    print(resp)

<Response [200]>

Request Payload 表示 http 请求中的有效载荷,就是 post 或 put 请求中所发送的数据内容,是 http 请求 headers 后的一部分,也就是请求体。

描述
application/x-www-form-urlencoded 在发送前编码所有字符(默认)
multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain 空格转换为 "+" 加号,但不对特殊字符编码。
application/json 消息主体是序列化后的 JSON 字符串
posted @ 2020-10-06 01:17  短戈行  阅读(119)  评论(0编辑  收藏  举报