Python3网络请求
本文主要介绍Python3网络请求的所使用的的模块request
- request是Python社区中最喜欢的库,因为它简洁易用。 request由urllib3提供支持,有玩笑说这是“唯一的非转基因HTTP库,适合人类消费”。
- request抽象了大量的程式化的代码,使得HTTP请求比使用内置urllib库更简单。
1. 安装
首先用pip进行安装
pip install requests
2. 模块说明
- requests是使用Apache2 licensed 许可证的HTTP库。
- 用python编写。
- 比urllib2模块更简洁。
- request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。
- 在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化,使用requests可以轻而易举的完成浏览器可有的任何操作。
- 现代,国际化,友好。
- requests会自动实现持久连接keep-alive
3. 基础入门
1)导入模块
import requests
2)发送请求的简洁
示例代码:获取一个网页(百度)
import requests
r = requests.get('https://www.baidu.com') # 最基本的不带参数的get请求
r1 = requests.get(url='https://api.apiopen.top/musicDetails', params={'id': '604392760'}) # 带参数的get请求
我们就可以使用该方式使用以下各种方法
requests.get(‘https://www.test.com/timeline’) # GET请求
requests.post(“http://www.test.com/post”) # POST请求
requests.put(“http://www.test.com/put”) # PUT请求
requests.delete(“http://www.test.com/delete”) # DELETE请求
requests.head(“http://www.test.com/get”) # HEAD请求
requests.options(“http://www.test.com/get” ) # OPTIONS请求
3)为url传递参数
url_params = {'key':'value'} # 字典传递参数,如果值为None的键不会被添加到url中
r = requests.get('your url',params = url_params)
print(r.url)
输出结果为:
your url?key=value
4)响应的内容
字段 | 含义 |
---|---|
r.encoding | #获取当前的编码 |
r.encoding = 'utf-8' | #设置编码 |
r.text | #以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。 |
r.content | #以字节形式(二进制)返回。字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩。 |
r.headers | #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None |
r.status_code | #响应状态码 |
r.raw | #返回原始响应体,也就是 urllib 的 response 对象,使用 r.raw.read() |
r.ok | # 查看r.ok的布尔值便可以知道是否登陆成功 |
r.json() | #Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常 |
r.raise_for_status() | #失败请求(非200响应)抛出异常 |
post发送json请求:
import requests
import json
r = requests.post('https://api.apiopen.top/getJoke', data=json.dumps({'id': 'data'}))
print(r.json())
5)定制头和cookie信息
header = {'user-agent': 'my-app/0.0.1''}
cookie = {'key':'value'}
r = requests.get/post('your url',headers=header,cookies=cookie)
import requests
import json
data = {'id': 'data'}
headers = {'content-type': 'application/json', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}
r = requests.post('https://api.apiopen.top/getJoke', data=json.dumps({'id': 'data'}, headers=headers)
print(r.text)
6)响应状态码
- 使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,如上实例中已经提到的 r.text、r.status_code……
- 获取文本方式的响应体实例:当你访问 r.text 之时,会使用其响应的文本编码进行解码,并且你可以修改其编码让 r.text 使用自定义的编码进行解码。
r = requests.get('http://www.baidu.com')
print(r.text, '\n{}\n'.format('*'*79), r.encoding)
r.encoding = 'GBK'
print(r.text, '\n{}\n'.format('*'*79), r.encoding)
示例代码:
# -*- coding: utf-8 -*-
# 打印中文需要的内容 开始
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
# 打印中文需要的内容 结束
import requests
r = requests.get(url='https://api.apiopen.top/musicDetails', params={'id': '604392760'}) # 带参数的get请求
print(r.url)
print(r.status_code) # 获取返回状态
print(r.text) # 打印解码后的返回数据
运行结果:
https://api.apiopen.top/musicDetails?id=604392760
200
{"code":200,"message":"成功!","result":{"xcode":"","songList":""}}
7)响应
字段 | 描述 |
---|---|
r.headers | #返回字典类型,头信息 |
r.requests.headers | #返回发送到服务器的头信息 |
r.cookies | #返回cookie |
r.history | #返回重定向信息,当然可以在请求是加上allow_redirects = false 阻止重定向</pre> |
8)超时
r = requests.get('url',timeout=1) #设置秒数超时,仅对于连接有效
9)会话对象,能够跨请求保持某些参数
s = requests.Session()
s.auth = ('auth','passwd')
s.headers = {'key':'value'}
r = s.get('url')
r1 = s.get('url1')
10)代理
proxies = {'http':'ip1','https':'ip2' }
requests.get('url',proxies=proxies)
汇总:
# HTTP请求类型 # get类型
requests.get(‘https://www.test.com/timeline’) # GET请求
requests.post(“http://www.test.com/post”) # POST请求
requests.put(“http://www.test.com/put”) # PUT请求
requests.delete(“http://www.test.com/delete”) # DELETE请求
requests.head(“http://www.test.com/get”) # HEAD请求
requests.options(“http://www.test.com/get” ) # OPTIONS请求
print(r.content) #以字节的方式去显示,中文显示为字符
print(r.text) #以文本的方式去显示
#URL传递参数
payload = {'tel': '18812345678'}
r = requests.get("https://tcc.taobao.com/cc/json/mobile_tel_segment.htm", params=payload)
print(r.url) #示例为https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=18812345678
#获取/修改网页编码
r = requests.get('https://www.baidu.com')
print (r.encoding)
#json处理
r = requests.get('https://api.apiopen.top/musicDetails')
print(r.json()) # 需要先import json
# 定制请求头
url = 'https://www.baidu.com'
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}
r = requests.post(url, headers=headers)
print (r.request.headers)
#复杂post请求
url = 'https://www.baidu.com'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload)) #如果传递的payload是string而不是dict,需要先调用dumps方法格式化一下
# post多部分编码文件
url = 'https://www.baidu.com'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files) # 响应状态码
r = requests.get('http://m.ctrip.com')
print(r.status_code) # 响应头
r = requests.get('http://m.ctrip.com')
print (r.headers)
print (r.headers['Content-Type'])
print (r.headers.get('content-type')) #访问响应头部分内容的两种方式
# Cookies
url = 'https://www.baidu.com'
r = requests.get(url)
r.cookies['example_cookie_name'] #读取cookies
url = 'http://m.ctrip.com/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies) #发送cookies
#设置超时时间
r = requests.get('https://www.baidu.com', timeout=0.001) #设置访问代理
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.100:4444"
}
r = requests.get('http://m.ctrip.com', proxies=proxies)
#如果代理需要用户名和密码,则需要这样:
proxies = {
"http": "http://user:password@10.10.1.10:3128/",
}
4、示例代码
1) GET请求
# -*- coding: utf-8 -*-
# 打印中文需要的内容 开始
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
# 打印中文需要的内容 结束
import requests
# 无参数请求
r = requests.get(url='https://m.baidu.com')
print(r.url)
print(r.status_code) # 获取返回状态
print(r.text)
# 有参数请求
r = requests.get(url='https://api.apiopen.top/musicDetails', params={'id': '604392760'}) # 带参数的get请求
print(r.url)
print(r.status_code) # 获取返回状态
print(r.text) # 打印解码后的返回数据
2) POST请求
# 1、基本POST实例
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.post("https://www.baidu.com", data=payload)
print(ret.text)
# 2、发送请求头和数据实例
import requests import json
url = 'https://www.baidu.com'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}
ret = requests.post(url, data=json.dumps(payload), headers=headers)
print(ret.text)
print(ret.cookies)
3) json请求:
#! /usr/bin/python3
import requests
import json
class url_request():
def __init__(self):
''' init '''
if __name__ == '__main__':
heard = {'Content-Type': 'application/json'}
payload = {'CountryName': '中国',
'ProvinceName': '四川省',
'L1CityName': 'chengdu',
'L2CityName': 'yibing',
'TownName': '',
'Longitude': '107.33393',
'Latitude': '33.157131',
'Language': 'CN'}
r = requests.post("http://www.xxxxxx.com/CityLocation/json/LBSLocateCity", heards=heard, data=payload)
data = r.json()
if r.status_code!=200:
print('LBSLocateCity API Error' + str(r.status_code))
print(data['CityEntities'][0]['CityID']) # 打印返回json中的某个key的value
print(data['ResponseStatus']['Ack'])
print(json.dump(data, indent=4, sort_keys=True, ensure_ascii=False)) # 树形打印json,ensure_ascii必须设为False否则中文会显示为unicode</pre>
4) Xml请求:
#! /usr/bin/python3
import requests
class url_request():
def __init__(self):
"""init"""
if __name__ == '__main__':
heards = {'Content-type': 'text/xml'}
XML = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Request xmlns="http://tempuri.org/"><jme><JobClassFullName>WeChatJSTicket.JobWS.Job.JobRefreshTicket,WeChatJSTicket.JobWS</JobClassFullName><Action>RUN</Action><Param>1</Param><HostIP>127.0.0.1</HostIP><JobInfo>1</JobInfo><NeedParallel>false</NeedParallel></jme></Request></soap:Body></soap:Envelope>'
url = 'http://jobws.push.mobile.xxxxxxxx.com/RefreshWeiXInTokenJob/RefreshService.asmx'
r = requests.post(url=url, heards=heards, data=XML)
data = r.text
print(data)
5) 状态异常处理
import requests
URL = 'http://ip.taobao.com/service/getIpInfo.php' # 淘宝IP地址库API
try:
r = requests.get(URL, params={'ip': '8.8.8.8'}, timeout=1)
r.raise_for_status() # 如果响应状态码不是 200,就主动抛出异常
except requests.RequestException as e:
print(e)
else:
result = r.json()
print(type(result), result, sep='\n')
6) 上传文件
使用request模块,也可以上传文件,文件的类型会自动进行处理:
import requests
url = 'http://127.0.0.1:8080/upload'
files = {'file': open('/home/rxf/test.jpg', 'rb')}
#files = {'file': ('report.jpg', open('/home/lyb/sjzl.mpg', 'rb'))} #显式的设置文件名
r = requests.post(url, files=files)
print(r.text)
request更加方便的是,可以把字符串当作文件进行上传:
import requests
url = 'http://127.0.0.1:8080/upload'
files = {'file': ('test.txt', b'Hello Requests.')} #必需显式的设置文件名
r = requests.post(url, files=files)
print(r.text)
7) 身份验证
基本身份认证(HTTP Basic Auth)
import requests from requests.auth
import HTTPBasicAuth
r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=HTTPBasicAuth('user', 'passwd'))
# r = requests.get('https://httpbin.org/hidden-basic-auth/user/passwd', auth=('user', 'passwd')) # 简写
print(r.json())
另一种非常流行的HTTP身份认证形式是摘要式身份认证,Requests对它的支持也是开箱即可用的:
requests.get(URL, auth=HTTPDigestAuth('user', 'pass'))
8) Cookies与会话对象
如果某个响应中包含一些Cookie,你可以快速访问它们:
import requests
r = requests.get('http://www.google.com.hk/') print(r.cookies['NID']) print(tuple(r.cookies))
要想发送你的cookies到服务器,可以使用 cookies 参数:
import requests
url = 'http://httpbin.org/cookies'
cookies = {'testCookies_1': 'Hello_Python3', 'testCookies_2': 'Hello_Requests'}
# 在Cookie Version 0中规定空格、方括号、圆括号、等于号、逗号、双引号、斜杠、问号、@,冒号,分号等特殊符号都不能作为Cookie的内容。
r = requests.get(url, cookies=cookies) print(r.json())
会话对象让你能够跨请求保持某些参数,最方便的是在同一个Session实例发出的所有请求之间保持cookies,且这些都是自动处理的,甚是方便。
下面就来一个真正的实例,如下是快盘签到脚本:
import requests
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, compress', 'Accept-Language': 'en-us;q=0.5,en;q=0.3', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'}
s = requests.Session()
s.headers.update(headers) # s.auth = ('superuser', '123')
s.get('https://www.kuaipan.cn/account_login.htm')
_URL = 'http://www.kuaipan.cn/index.php' s.post(_URL, params={'ac':'account', 'op':'login'},
data={'username':'****@foxmail.com', 'userpwd':'********', 'isajax':'yes'})
r = s.get(_URL, params={'ac':'zone', 'op':'taskdetail'})
print(r.json())
s.get(_URL, params={'ac':'common', 'op':'usersign'})</pre>