Skip to main content

Http

requests 是 Python 的 Http 请求库,AScript 中内置了这个库

# 导包
import requests

GET 请求

基本 GET 请求

import requests

r = requests.get("http://www.baidu.com")
# 打印状态码
print(r.status_code)
# 打印返回文本
print(r.text)

带参数的 GET 请求

import requests

# 方式1: 参数拼在 URL 中
r = requests.get("https://httpbin.org/get?name=airscript&version=3.3")
print(r.text)

# 方式2: 通过 params 传参 (推荐)
params = {"name": "airscript", "version": "3.3"}
r = requests.get("https://httpbin.org/get", params=params)
print(r.json())

GET 请求返回 JSON

import requests

r = requests.get("http://www.weather.com.cn/data/sk/101010100.html")
r.encoding = r.apparent_encoding
obj = r.json()
print(obj['weatherinfo']['city'])

POST 请求

Form 表单提交

import requests

r = requests.post("https://httpbin.org/post", data={"user": "test", "pwd": "123"})
print(r.text)

JSON 提交

import requests

# 推荐: 直接使用 json 参数, 自动序列化和设置 Content-Type
r = requests.post("https://httpbin.org/post", json={"key1": "value1", "key2": "value2"})
print(r.json())

上传文件

import requests
from ascript.android.system import R

# 上传单个文件
files = {"file": open(R.res("1.png"), "rb")}
r = requests.post("https://httpbin.org/post", files=files)
print(r.status_code)
import requests
from ascript.android.system import R

# 上传文件同时附带表单参数
files = {"file": ("image.png", open(R.res("1.png"), "rb"), "image/png")}
data = {"description": "测试图片"}
r = requests.post("https://httpbin.org/post", files=files, data=data)
print(r.text)

其他请求方法

import requests

# PUT 请求
r = requests.put("https://httpbin.org/put", json={"key": "value"})

# DELETE 请求
r = requests.delete("https://httpbin.org/delete")

# PATCH 请求
r = requests.patch("https://httpbin.org/patch", json={"key": "new_value"})

请求头设置

自定义 Headers

import requests

headers = {
"User-Agent": "AScript/3.3",
"Authorization": "Bearer your_token_here",
"Content-Type": "application/json"
}
r = requests.get("https://httpbin.org/headers", headers=headers)
print(r.json())

模拟浏览器请求

import requests

headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0 Safari/537.36"
}
r = requests.get("https://www.baidu.com", headers=headers)
r.encoding = "utf-8"
print(r.text)

import requests

cookies = {"session_id": "abc123", "user": "test"}
r = requests.get("https://httpbin.org/cookies", cookies=cookies)
print(r.json())
import requests

r = requests.get("https://www.baidu.com")
for key, value in r.cookies.items():
print(f"{key} = {value}")

使用 Session 保持会话

import requests

# Session 会自动管理 Cookie, 适合需要登录的场景
s = requests.Session()

# 第一次请求: 登录
s.post("https://example.com/login", data={"user": "test", "pwd": "123"})

# 后续请求: 自动携带登录后的 Cookie
r = s.get("https://example.com/profile")
print(r.text)

s.close()

响应处理

常用响应属性

import requests

r = requests.get("https://httpbin.org/get")

print(r.status_code) # 状态码: 200
print(r.headers) # 响应头 (字典)
print(r.headers['content-type']) # 指定响应头
print(r.encoding) # 编码
print(r.text) # 文本内容
print(r.content) # 二进制内容 (bytes)
print(r.json()) # JSON 解析为字典
print(r.url) # 最终请求的 URL
print(r.elapsed) # 请求耗时

判断请求是否成功

import requests

r = requests.get("https://httpbin.org/get")

if r.status_code == 200:
print("请求成功")
print(r.json())
else:
print(f"请求失败, 状态码: {r.status_code}")
import requests

r = requests.get("https://httpbin.org/get")

# 如果状态码不是 2xx, 会抛出异常
r.raise_for_status()
print(r.json())

超时与重试

设置超时

import requests

try:
# timeout 单位为秒, 超过时间未响应会抛出异常
r = requests.get("https://httpbin.org/delay/5", timeout=3)
print(r.text)
except requests.exceptions.Timeout:
print("请求超时!")
except requests.exceptions.ConnectionError:
print("连接失败!")

简单重试

import requests
import time

def request_with_retry(url, max_retries=3):
for i in range(max_retries):
try:
r = requests.get(url, timeout=5)
r.raise_for_status()
return r
except Exception as e:
print(f"第{i+1}次请求失败: {e}")
if i < max_retries - 1:
time.sleep(2)
return None

r = request_with_retry("https://httpbin.org/get")
if r:
print(r.json())

下载文件

小文件下载

import requests
from ascript.android.system import R

url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png"
r = requests.get(url)

with open(R.res("logo.png"), "wb") as f:
f.write(r.content)

print("下载完成")

大文件下载(流式)

import requests
from ascript.android.system import R

url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png"
r = requests.get(url, stream=True)

with open(R.res("logo.png"), "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)

print("下载完成")

带进度的下载

import requests
from ascript.android.system import R

url = "https://www.baidu.com/img/flexible/logo/pc/result@2.png"
r = requests.get(url, stream=True)

total = int(r.headers.get('content-length', 0))
downloaded = 0

with open(R.res("logo.png"), "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
downloaded += len(chunk)
if total > 0:
percent = downloaded * 100 // total
print(f"下载进度: {percent}%")

print("下载完成")

异常处理

import requests

try:
r = requests.get("https://httpbin.org/get", timeout=5)
r.raise_for_status()
data = r.json()
print(data)
except requests.exceptions.Timeout:
print("请求超时")
except requests.exceptions.ConnectionError:
print("网络连接失败")
except requests.exceptions.HTTPError as e:
print(f"HTTP 错误: {e}")
except requests.exceptions.RequestException as e:
print(f"请求异常: {e}")