测试学习之——requests day01
一、requests准备
1、下载第三方requests请求
终端命令:
pip install requests
此命令可在电脑终端执行但要先准备python3环境,也可在pycharm软件终端执行。
2、准备pycharm软件
pycharm官网:PyCharm: The only Python IDE you need
3、request的具体作用
作为中间件为前后端的互联做媒介。
二、requests GET请求创建
步骤:
1、倒包:倒入requests包
2、requests请求创建
3、打印相应信息
import requestsdef test_api():r = requests.get(url = "https://www.baidu.com/")print(r.text) #打印返回正文信息print(r.encoding) #返回编码方式print(r.url)#返回请求的urlprint(r.headers) #返回请求头信息print(r.cookies) #返回cookies信息print(r.content) #返回正文信息,二进制保存
GET请求示例:
#倒包
import requests#淘宝查询手机号码归属地的接口
'''
接口的url地址:
接口请求方式:get
接口的请求参数:tel
'''
#定义一个变量
url = "https://cn.apihz.cn/api/ip/shouji.php?id=88888888&key=88888888&phone=13219931963"
#get请求,请求数据保存两种方式
#1保存在url中,?后面添加 参数名与参数值 ,多个参数用&连接
def test_api():r = requests.get(url = url)print(r.text)#响应数据print(r.status_code)#状态码print(r.cookies)# cookies数据print(r.url)#请求的url地址
#第二种:参数保存在 params
#params 用字典格式保存参数
url1="https://cn.apihz.cn/api/ip/shouji.php"
params ={"id":88888888,"key":88888888,"phone":13219931963
}
def test_api1():r= requests.get(url = url1,params = params)print(r.text) # 响应数据print(r.status_code) # 状态码print(r.cookies) # cookies数据print(r.url) # 请求的url地址
三、requests POST请求创建
步骤:
1、倒包:倒入requests包
2、requests请求创建
3、打印相应信息
POST请求示例:
实现接口前需安装flask依赖:
pip install flask
注册接口:
from flask import Flask, request, jsonifyapp = Flask(__name__)# 模拟数据库存储用户信息
users_db = {}@app.route('/')
def home():return jsonify({'message': 'Welcome to the registration API','endpoints': {'register': '/register (POST)'}})@app.route('/register', methods=['POST'])
def register():# 获取请求参数username = request.form.get('username')password = request.form.get('password')# 验证参数是否存在if not username or not password:return jsonify({'code': 400,'message': 'Username and password are required','data': None}), 400# 检查用户名是否已存在if username in users_db:return jsonify({'code': 400,'message': 'Username already exists','data': None}), 400# 存储用户信息(实际应用中应该加密存储密码)users_db[username] = {'password': password, # 注意:实际应用中应该使用密码哈希'created_at': '2025-07-22T10:02:26' # 示例时间}# 返回成功响应return jsonify({'code': 200,'message': 'Registration successful','data': {'username': username}})if __name__ == '__main__':app.run(debug=True)
注册POST请求测试示例:
#1:倒包
import requests
#2注册接口
url_reg="http://127.0.0.1:5000/register"
#表单数据格式,参数是data,数据是字典保存
data = {"username":"cy201","password":"123456"
}
def test_api():r_reg = requests.post(url = url_reg ,data=data)print(r_reg.text)print(r_reg.status_code) # 状态码
结果:
登录接口:
from flask import Flask, request, jsonify
from werkzeug.security import generate_password_hash, check_password_hash
import datetimeapp = Flask(__name__)# 模拟用户数据库
users_db = {"admin": {"password_hash": generate_password_hash("admin123"), # 自动生成密码哈希"created_at": datetime.datetime.now().isoformat()}
}@app.route('/login', methods=['POST'])
def login():# 获取JSON数据data = request.get_json()# 验证数据格式if not data or 'username' not in data or 'password' not in data:return jsonify({'code': 400,'message': 'Username and password are required in JSON format','data': None}), 400username = data['username']password = data['password']# 检查用户是否存在if username not in users_db:return jsonify({'code': 401,'message': 'Invalid username or password','data': None}), 401# 验证密码if not check_password_hash(users_db[username]['password_hash'], password):return jsonify({'code': 401,'message': 'Invalid username or password','data': None}), 401# 登录成功return jsonify({'code': 200,'message': 'Login successful','data': {'username': username,'login_time': datetime.datetime.now().isoformat()}})@app.route('/')
def home():return jsonify({'message': 'Login API is running','endpoint': '/login (POST)','parameters': {'username': 'string','password': 'string'}})if __name__ == '__main__':app.run(debug=True)
登录POST请求测试示例:
#1:倒包
import requests
#登录接口
url_login = "http://127.0.0.1:5000/login"#json数据格式
#发丝请求
json ={"username":"admin","password":"admin123"
}
def test_api1():r_login=requests.post(url = url_login,json=json)print(r_login.text)print(r_login.status_code)
结果:
四、requests的headers参数
hearders发送请求,该参数不是每个接口都必须要添加的,都是开发可以定义的
1、不需要添加headers 前程无忧搜索职位接口
步骤:
1.打开前程无忧网站:
2.打开前程无忧的调试工具(一般默认F12)
3.选择network ,进行抓包,如果原理有抓包信息,先清空
4.搜索职位,点滴搜索
5.抓包获取参数
import requests
url = 'https://we.51job.com/api/job/search-pc?api_key=51job×tamp=1753153055&keyword=%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%E5%B7%A5%E7%A8%8B%E5%B8%88&searchType=2&function=&industry=&jobArea=080200%2C020000%2C040000&jobArea2=&landmark=&metro=&salary=&workYear=°ree=&companyType=&companySize=&jobType=&issueDate=&sortType=0&pageNum=1&requestId=&pageSize=20&source=1&accountId=231081051&pageCode=sou%7Csou%7Csoulb&scene=7'
def test_51job():r_518job=requests.get(url = url)#滑动验证print(r_518job.status_code)#打印返回的中文为乱码print(r_518job.encoding)#打印返回html界面的编码方式,ISO-8859-1#修改返回编码方式r_518job.encoding ='utf-8'print(r_518job.text)
2、需要添加headers 12306查询车票接口
步骤:
1.打开12306网站:
2.打开调试工具(一般默认F12)
3.选择network ,进行抓包,如果原理有抓包信息,先清空
4.搜索车票
5.抓包获取参数
import requests
url12306 ='https://kyfw.12306.cn/otn/leftTicket/queryU?leftTicketDTO.train_date=2025-07-22&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT'
#需要添加的headers的哪些参数,工作中询问开发人员,做了哪些判断
headers ={'Cookie':'_uab_collina=172943520463509477448666; JSESSIONID=4C3315F0A582596707FA4CC8DE200F9B; _jc_save_wfdc_flag=dc; BIGipServerotn=1859715338.50210.0000; BIGipServerpassport=904397066.50215.0000; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; route=495c805987d0f5c8c84b14f60212447d; _jc_save_fromDate=2025-07-22; _jc_save_toDate=2025-07-22; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_toStation=%u4E0A%u6D77%2CSHH'
}
def test_12306():r_12306 = requests.get(url=url12306, headers=headers)print(r_12306.status_code)print(r_12306.encoding)r_12306.encoding = 'utf-8'print(r_12306.text)
五、响应内容
概念:当客户端向服务器发送请求后,服务器会返回一个Response对象,包含了所有的服务器响应信息。
1、文本内容
import requests
def test_github():r = requests.get("https://api.github.com/events")print(r.text) #打印响应信息
请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当你访问 r.text
之时,Requests 会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding
属性来改变它:
import requests
def test_github():r = requests.get("https://api.github.com/events")print('\n'+r.encoding)>>>'utf-8'r.encoding = 'ISO-8859-1'#修改文件编码为ISO-8859-1print(r.text)
如果你改变了编码,每当你访问 r.text
,Request 都将会使用 r.encoding
的新值。你可能希望在使用特殊逻辑计算出文本的编码的情况下来修改编码。比如 HTTP 和 XML 自身可以指定编码。这样的话,你应该使用 r.content
来找到编码,然后设置 r.encoding
为相应的编码。这样就能使用正确的编码解析 r.text
了。
在你需要的情况下,Requests 也可以使用定制的编码。如果你创建了自己的编码,并使用 codecs
模块进行注册,你就可以轻松地使用这个解码器名称作为 r.encoding
的值, 然后由 Requests 来为你处理编码
2、二进制响应内容
你也能以字节的方式访问请求响应体,对于非文本请求:
import requests
def test_github():r = requests.get("https://api.github.com/events")print(r.content)
Requests 会自动为你解码 gzip
和 deflate
传输编码的响应数据。
例如,以请求返回的二进制数据创建一张图片,你可以使用如下代码:
import requests
from io import BytesIO
from PIL import Image
def test_github():r = requests.get("https://api.github.com/events")i = Image.open(BytesIO(r.content))
此代码会报错,因为
- GitHub API 返回的是 JSON 数据
https://api.github.com/events
返回的是事件日志(JSON 格式),不是图像二进制数据。
Image.open()
只能处理图像文件
Pillow 支持 JPEG/PNG/GIF 等图像格式,但无法解析 JSON 或其他非图像数据。
3、JSON响应内容
Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据:
import requestsdef test_github():r = requests.get("https://api.github.com/events")print(r.json())
如果 JSON 解码失败, r.json()
就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json()
将会抛出 ValueError: No JSON object could be decoded
异常。
需要注意的是,成功调用 r.json()
并**不**意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status()
或者检查 r.status_code
是否和你的期望相同。
4、原始响应内容
在罕见的情况下,你可能想获取来自服务器的原始套接字响应,那么你可以访问 r.raw
。 如果你确实想这么干,那请你确保在初始请求中设置了 stream=True
。具体你可以这么做:
import requestsdef test_github():r = requests.get("https://api.github.com/events",stream = True)print(r.raw)print(r.raw.read(10))
但在一般情况下,应该使用下面的模式将文本流保存到文件:
with open(filename, 'wb') as fd:for chunk in r.iter_content(chunk_size):fd.write(chunk)
使用 Response.iter_content
将会处理大量你直接使用 Response.raw
不得不处理的。 当流下载时,上面是优先推荐的获取内容方式。 Note that chunk_size
can be freely adjusted to a number that may better fit your use cases.
5、定制请求头
如果你想为请求添加 HTTP 头部,只要简单地传递一个 dict
给 headers
参数就可以了。
例如,在前一个示例中我们没有指定 content-type:
import requests
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}def test_github():r = requests.get("https://api.github.com/events",headers = headers)
注意: 定制 header 的优先级低于某些特定的信息源,例如:
- 如果在
.netrc
中设置了用户认证信息,使用 headers= 设置的授权就不会生效。而如果设置了auth=
参数,``.netrc`` 的设置就无效了。 - 如果被重定向到别的主机,授权 header 就会被删除。
- 代理授权 header 会被 URL 中提供的代理身份覆盖掉。
- 在我们能判断内容长度的情况下,header 的 Content-Length 会被改写。
更进一步讲,Requests 不会基于定制 header 的具体情况改变自己的行为。只不过在最后的请求中,所有的 header 信息都会被传递进去。
注意: 所有的 header 值必须是 string
、bytestring 或者 unicode。尽管传递 unicode header 也是允许的,但不建议这样做。
6、响应码状态
import requests
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}def test_github():r = requests.get("https://api.github.com/events",headers = headers)print(r.status_code)
为方便引用,Requests还附带了一个内置的状态码查询对象:
import requests
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}def test_github():r = requests.get("https://api.github.com/events",headers = headers)print(r.status_code == requests.codes.ok)
7、响应头
我们可以查看以一个 Python 字典形式展示的服务器响应头:
import requests
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}def test_github():r = requests.get(url=url,headers = headers)print(r.headers)
但是这个字典比较特殊:它是仅为 HTTP 头部而生的。根据 RFC 2616, HTTP 头部是大小写不敏感的。
因此,我们可以使用任意大写形式来访问这些响应头字段:
import requests
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}def test_github():r = requests.get(url=url,headers = headers)print(r.headers)>>> r.headers['Content-Type']
'application/json'>>> r.headers.get('content-type')
'application/json'
它还有一个特殊点,那就是服务器可以多次接受同一 header,每次都使用不同的值。但 Requests 会将它们合并,这样它们就可以用一个映射来表示出来,参见 RFC 7230:
A recipient MAY combine multiple header fields with the same field name into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma.
接收者可以合并多个相同名称的 header 栏位,把它们合为一个 "field-name: field-value" 配对,将每个后续的栏位值依次追加到合并的栏位值中,用逗号隔开即可,这样做不会改变信息的语义。
8、cookie
如果某个响应中包含一些 cookie,你可以快速访问它们:
import requests
url = 'http://example.com/some/cookie/setting/url'def test_github():r = requests.get(url= url)r.cookies['example_cookie_name']
要想发送你的cookies到服务器,可以使用 cookies
参数:
>>> url = 'http://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'
Cookie 的返回对象为 RequestsCookieJar,它的行为和字典类似,但接口更为完整,适合跨域名跨路径使用。你还可以把 Cookie Jar 传到 Requests 中:
>>> 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)
>>> r.text
'{"cookies": {"tasty_cookie": "yum"}}'
六、带参数请求
GET 请求:
- 参数通常附加在URL 的末尾,以
?
符号分隔,例如:https://example.com/resource?param1=value1¶m2=value2
。 - 使用
?
符号将参数与URL 分隔,参数之间使用&
符号分隔,每个参数都是键值对的形式,例如param1=value1
和param2=value2
。 - 用于获取数据,例如搜索、过滤等。
POST 请求:
- 参数可以包含在请求体中,常见的格式有:
-
form-data
:适用于上传文件等,参数以键值对的形式发送,每个参数都是独立的。x-www-form-urlencoded
:类似于表单提交,参数以键值对的形式发送,参数之间用&
分隔,编码后发送。raw
:可以发送任意格式的数据,例如JSON、XML 等。
- 用于提交数据,例如表单提交、上传文件等。