跳到主要内容
版本:2.20.0

脚本API

脚本框架中涉及的python类的API文档说明。

提示

变量名斜体表示只读,粗体表示可覆写。

CaptureContext

变量类型说明
urlstr请求url,只读。
schemestr请求标志符,值为http或https,只读。
hoststr域名,只读。
portint端口号,只读。
cidintTCP连接ID,只读。
ctimeintTCP连接开始时间戳,单位毫秒,只读。
sidintHTTP会话ID,只读。
stimeintHTTP会话开始时间戳,单位毫秒,只读。
uidstrHTTP会话的唯一标志,由 ctime + cid + sid 组成。
envdict全局环境和当前已激活的自定义环境的变量合集。
appCaptureApp应用(进程)信息,未获取到为None。
shared-用于 onRequestonResponse 之间共享数据的特殊变量,可以是str、int、list和dict等可自动序列化的变量。

代码示例:

def onRequest(context, request):
# 打印url,例如:https://reqable.com/
print(context.url)
# 打印schema,例如:https
print(context.scheme)
# 打印host,例如:reqable.com
print(context.host)
# 打印port,例如:443
print(context.port)
# 打印TCP连接ID,例如:1
print(context.cid)
# 打印TCP连接开始时间,例如:1686711219444
print(context.ctime)
# 打印HTTP的会话ID,例如:1
print(context.sid)
# 打印HTTP的会话开始时间,例如:1686711224132
print(context.stime)

# 获取环境变量
print(context.env['foo'])
print(context.env['$timestamp'])

# 写入环境变量(优先写入当前激活的自定义环境,没有激活环境则写入全局环境)
context.env['foo'] = 'bar'

# 设置共享参数
context.shared = 'Hello'

# Done
return request

def onResponse(context, response):
# 打印共享参数,输出:Hello
print(context.shared)
return response

CaptureHttpRequest

变量类型说明
methodstr请求方法。
pathstr请求路径,注意不包含query部分。
protocolstr请求的HTTP协议版本,只读。
queriesCaptureHttpQueries请求参数列表。
headersCaptureHttpHeaders请求头列表。
bodyCaptureHttpBody请求体。
trailersCaptureHttpHeaders请求尾部列表,参见HTTP1的chunked trailers或者HTTP2的trailers。注意此功能待验证,暂时请勿使用。
contentTypestr或None请求类型(即headers中的Content-Type的值),只读。
mimestr或None请求MIME类型,例如application/json,只读。

代码示例:

def onRequest(context, request):
# 打印请求方法,例如:POST
print(request.method)
# 打印请求路径,例如:/foo
print(request.path)
# 打印请求参数列表,例如:[('foo', 'bar'), ('hello', 'world')]
print(request.queries)
# 打印请求头列表,例如:['host: reqable.com', 'content-length: 6', 'content-type: text/plain']
print(request.headers)
# 打印请求体,例如 {"foo":"bar"}
print(request.body)

# 修改请求方法
request.method = 'GET'
# 修改请求路径
request.path = '/bar'

# 修改请求参数,更多API请参考下文`CaptureHttpQueries`
request.queries['foo'] = 'bar'
# 直接赋值请求参数
request.queries = 'foo=bar&hello=world&abc=123'
request.queries = {
'foo': 'bar',
'hello': 'world',
'abc': '123'
}
# 删除指定请求参数
request.queries.remove('foo')

# 修改请求头,更多API请参考下文`CaptureHttpHeaders`
request.headers['content-type'] = 'application/json'
# 直接赋值请求头
request.headers = [
'content-type: application/json',
'foo: bar'
]
# 删除指定请求头
request.headers.remove('foo')

# 将文本设置给Body
request.body = 'Hello World'
# 将字典设置给Body,会自动转成JSON
request.body = {
'foo': 'bar',
'abc': 123
}
# 将二进制数据设置给Body
request.body = b'\x01\x02\x03\x04'
# 将本地文件设置给Body
request.body.file('/User/Reqable/Desktop/test.png')

# JSON类型的Body转成字典
request.body.jsonify()
# 然后操作字典来修改Body
request.body['foo'] = 'bar'
request.body['error'] = {
'code': 1000,
'message': 'Runtime Error'
}

# Done
return request

CaptureHttpResponse

变量类型说明
requestCaptureHttpRequest响应的请求信息,只读。
codeint响应状态码。
messagestr响应状态信息,只读。注意:HTTP2协议中,值为空;此值在状态码修改后会自动更新。
protocolstr响应的HTTP协议版本,只读。
headersCaptureHttpHeaders响应头列表。
bodyCaptureHttpBody响应体。
trailersCaptureHttpHeaders响应尾部列表,参见HTTP1的chunked trailers或者HTTP2的trailers。注意此功能待验证,暂时请勿使用。
contentTypestr或None响应类型(即headers中的Content-Type的值),只读。
mimestr或None响应MIME类型,例如application/json,只读。

代码示例:

def onResponse(context, response):
# 打印请求信息,更多API请参考上文`CaptureHttpRequest`
print(response.request)
# 打印响应状态码,例如:200
print(response.code)
# 打印响应消息
print(response.message)
# 打印响应头列表,例如:['server: Netlify', 'content-length: 6', 'content-type: text/plain']
print(response.headers)
# 打印响应体,例如 {"foo":"bar"}
print(response.body)

# 修改响应状态码
response.code = 400

# 更多的示例参考上面的`onRequest`,完全一样。

# Done
return response

CaptureHttpQueries

函数参数返回说明
lenint返回query参数的个数。
iter支持迭代遍历全部的query参数。
addstr, str新增一个query,参数为name和value。
removestr删除指定name的query。注意:如果有多个同名的,全部会移除。
clear清空所有query。
concatboolstr返回拼接好的完整query字符串。
indexstrint查询指定name的query参数在列表中的索引,只返回第一个匹配name的索引。
indexesstrlist查询指定name的query参数在列表中的索引,返回全部匹配name的索引列表。
getitemstrstr获取指定name的query值。注意:如果有多个同名的,会返回第一个;如果不存在,则返回None。
getiteminttuple按照索引获取query的名称和值。
setitemstr, str更新或新增query。如果存在指定name的query,则更新它的值,否则添加一个新的query参数。

代码示例:

def onRequest(context, request):
# 打印query参数个数
print(len(request.queries))
# 遍历query参数
for query in request.queries:
print(query)

# 新增query参数
request.queries.add('foo', 'bar')
# 移除query参数
request.queries.remove('foo')
# 清空全部query参数
request.queries.clear()
# 更新query参数,如果不存在则自动新增
request.queries['foo'] = 'bar'

# 打印指定query参数值,例如bar
print(request.queries['foo'])
# 打印指定索引位置的query名称和值,例如(foo, bar)
print(request.queries[0])
# 打印拼接好的完整Query字符串,例如foo=bar&hello=world
print(request.concat())
# 打印拼接好的完整Query字符串(urlencode参数值)
print(request.concat(encode=True))

# Done
return request

CaptureHttpHeaders

函数参数返回说明
lenint返回header的个数。
iter支持迭代遍历全部的header。
addstr, str新增一个header,参数为name和value。
removestr删除指定name的header。注意:如果有多个同名的,全部会移除。
clear清空所有header。
indexstrint查询指定name的header参数在列表中的索引,只返回第一个匹配name的索引。
indexesstrlist查询指定name的header参数在列表中的索引,返回全部匹配name的索引列表。
getitemstrstr获取指定name的header值。注意:如果有多个同名的,会返回第一个;如果不存在,则返回None。
getitemintstr按照索引获取header的名称和值。
setitemstr, str更新或新增header。如果存在指定name的header,则更新它的值,否则添加一个新的header。

代码示例:

def onRequest(context, request):
# 打印headers参数个数
print(len(request.headers))
# 遍历header
for header in request.headers:
print(header)
# 新增header
request.headers.add('foo', 'bar')
# 移除header
request.headers.remove('foo')
# 清空全部header
request.headers.clear()
# 更新header,如果不存在则自动新增
request.headers['foo'] = 'bar'
# 打印指定header值,例如bar
print(request.headers['foo'])
# 打印指定索引位置的header名称和值,例如`foo: bar`
print(request.headers[0])
# Done
return request

CaptureHttpBody

变量类型说明
isNonebool判断是否是空Body。此类型时,payload为None。
isTextbool判断是否是字符串Body。此类型时,payload为str。
isBinarybool判断是否是二进制Body。此类型时,payload为bytes。
isMultipartbool判断是否是Form Body。此类型时,payload为CaptureHttpMultipartBody的列表。
typeint返回Body的类型。0表示空,1表示字符串,2表示二进制,3表示Form。
payload多态类型,参照上方说明。Body的数据。
def onRequest(context, request):
# 判断body类型
print(request.body.type)
if request.body.isNone:
print('Http body is none')
elif request.body.isText:
print('Http body is text')
elif request.body.isBinary:
print('Http body is binary')
elif request.body.isMultipart:
print('Http body is multipart')

# 打印Body的类型
print(request.body.type)
# 打印Body的数据
print(request.body.payload)
函数参数返回说明
none设置为空Body。
textstr设置为字符串Body,内容为参数值。
textFromFilestr设置为字符串Body,并从指定文件路径中读取字符串数据。
binarystr或bytes设置为字节Body,参数为str时表示从指定文件路径中读取数据。
filestr设置为字节Body,表示从指定文件路径中读取数据,功能同上面的binary函数。
multipartslist设置为Multipart Body,参数为CaptureHttpMultipartBody的列表。
writeFilestr将Body数据写入文件。注意:不支持Multipart类型Body。

代码示例:

def onRequest(context, request):
# 修改body为空
request.body.none()
# 修改body为字符串
request.body.text('foobar')
# 修改body为字符串,内容从文件读取
request.body.textFromFile('/User/Reqable/Desktop/body.json')
# 修改body为字节序列,直接指定
request.body.binary(b'\x01\x02\x03\x04')
# 修改body为字节序列,内容从文件读取
request.body.binary('~/Desktop/body.json')
# 修改body为multipart类型
request.body.multiparts([
CaptureHttpMultipartBody.text('Hi World'),
CaptureHttpMultipartBody.file('data/body_binary.bin')
])

# 将body数据写入文件
request.body.writeFile('/User/Reqable/Desktop/body.json')

# Done
return request

CaptureHttpMultipartBody

CaptureHttpMultipartBody继承于CaptureHttpBody,额外多出一个headers属性。

变量类型说明
headersCaptureHttpHeaders分部头部。
namestr分部名称。
filenamestr分部文件名。

代码示例:

def onRequest(context, request):
# 遍历parts
for part in request.body:
print(f'name {part.name}')
print(f'filename {part.filename}')
print(f'value {part}')

# 修改parts
request.body[0] = CaptureHttpMultipartBody.text('Hi World')
request.body[0] = CaptureHttpMultipartBody.text('Hi World', name='reqable')
request.body[0] = CaptureHttpMultipartBody.file('data/body_binary.bin')
request.body[0] = CaptureHttpMultipartBody.file('data/body_binary.bin', name='reqable', filename='test.png')

# Done
return request
警告

如果将非multipart类型修改成multipart类型,必须同时修改headers设置boundary!

CaptureApp

变量类型说明
namestr应用(进程)名称。
idstr应用ID,未获取到为None。例如Android上是packageName,Mac上是bundleId
pathstr应用执行文件路径,未获取到为None。

代码示例:

def onRequest(context, response):
# 打印应用信息
print(context.app.name)
print(context.app.id)
print(context.app.path)
# Done
return request

示例1

下面是一个修改JSON响应数据的示例。

假设响应数据是下面的格式:

{
"code": 10000,
"message": "ok",
"content": {
"version": "1.0.0",
"platform": "windows"
}
}

我们需要将version的值修改为2.0.0

from reqable import *

def onRequest(context, request):
# Done
return request

def onResponse(context, response):
# 将响应体字典化
response.body.jsonify()
# 修改字典中的version值
response.body['content']['version'] = '2.0.0'
# Done
return response

示例2

下面是一个自动给请求参数进行MD5签名的示例。

from reqable import *
import hashlib

def onRequest(context, request):
# 对query列表进行排序
request.queries = sorted(request.queries)
# 拼接query数据
text = request.queries.concat()
# 选用md5算法进行签名
algorithm = hashlib.md5()
# 计算字符串的签名
algorithm.update(text.encode(encoding='UTF-8'))
signature = algorithm.hexdigest()
# 签名加到请求头中
request.headers['signature'] = signature
# Done
return request

def onResponse(context, response):
# Done
return response

示例3

下面是一个自动保存图片的脚本示例。

from reqable import *
from mimetypes import guess_extension
import datetime
import os

def onRequest(context, request):
return request

def onResponse(context, response):
# 检查Mime类型,非图片类型则跳过不处理
mime = response.mime
if mime == None:
return response

maintype, subtype = mime.split('/')
if not maintype == 'image':
return response

# 保存图片到指定目录,文件名为时间戳,后缀根据Mime类型推导
dir = '/Users/megatronking/Downloads/reqable/'
os.makedirs(dir, exist_ok=True)
name = datetime.datetime.now().strftime("%H%M%S%f")
ext = guess_extension(mime)
image = os.path.join(dir, name + ext)

# 响应体写入文件
print(f'Saving image {image}')
response.body.writeFile(image)

# Done
return response

实战教程

Reqable脚本功能实战案例