配置

hs-net 提供灵活的配置方式,支持全局配置、构造函数参数和请求级参数三级覆盖。

NetConfig

NetConfig 是全局配置类,所有选项都有合理的默认值:

config.py
from hs_net import NetConfig, EngineEnum, DEFAULT_USER_AGENT

config = NetConfig(
    engine=EngineEnum.HTTPX,    # HTTP 引擎
    base_url="",                # 基础 URL
    timeout=20.0,               # 超时时间(秒)
    retries=3,                  # 重试次数
    retry_delay=0.0,            # 重试间隔(秒)
    user_agent=DEFAULT_USER_AGENT,  # User-Agent,默认当前版桌面 Chrome
    proxy=None,                 # 代理地址(支持字符串或 ProxyService)
    verify=False,               # SSL 证书验证(默认关闭)
    raise_status=True,          # 非 2xx 是否抛异常
    allow_redirects=True,       # 是否跟随重定向
    rate_limit=None,            # 速率限制(int/float 或 RateLimitConfig)
    concurrency=None,           # 最大并发数
    headers={},                 # 全局请求头
    cookies={},                 # 全局 cookies
    engine_options={},          # 引擎特定配置
)

配置选项详解

engine

指定 HTTP 引擎,支持字符串或枚举:

# 字符串
net = SyncNet(engine="curl_cffi")

# 枚举
net = SyncNet(engine=EngineEnum.CURL_CFFI)

# 自定义引擎类
net = SyncNet(engine=MyCustomEngine)

base_url

设置基础 URL,请求时自动拼接路径:

base_url.py
net = SyncNet(base_url="https://api.example.com/v1")

# 以下两种写法等价:
net.get("/users")       # => https://api.example.com/v1/users
net.get("users")        # => https://api.example.com/v1/users

# 绝对 URL 不受 base_url 影响
net.get("https://other.com/path")  # => https://other.com/path

user_agent

默认是当前版本的桌面 Chrome,无需配置。要换用内置的真实 UA 池,传快捷方式即可(不区分大小写):

net = SyncNet(user_agent="random")      # 任意桌面浏览器
net = SyncNet(user_agent="chrome")      # 指定浏览器
net = SyncNet(user_agent="mobile")      # 任意移动端浏览器
net = SyncNet(user_agent="android")     # 指定移动平台
net = SyncNet(user_agent="bot")         # 任意搜索引擎爬虫
net = SyncNet(user_agent="baiduspider") # 指定爬虫
net = SyncNet(user_agent="wechat")      # 微信内置浏览器
net = SyncNet(user_agent="MyBot/1.0")   # 自定义 UA,原样使用
类别快捷方式
桌面浏览器randomchromefirefoxff)、edgesafari
移动端浏览器mobileandroidiosiphone
搜索引擎爬虫botgooglebotgoogle)、bingbotbing)、baiduspiderbaidu)、sogou360spiderbytespiderbytedance/toutiao)、yandexbotyandex)、duckduckbotapplebot
App 内置浏览器wechatweixin/micromessenger

randommobile 是桌面、移动端各自的随机入口。爬虫和微信有特定用途,需要显式指定,不会被随机取到。不在上表中的字符串一律当作自定义 UA 使用。

UA 数据内置在包里(约 13 KB,无额外依赖),由 scripts/gen_ua_data.py 从上游源合并生成,刷新只需重跑该脚本。

verify

是否验证 SSL 证书(默认关闭):

net = SyncNet(verify=True)   # 开启 SSL 验证(生产环境推荐)
net = SyncNet(verify=False)  # 跳过 SSL 验证(默认)

rate_limit

速率限制,控制请求频率:

from hs_net import RateLimitConfig

# 简单全局限速:每秒最多 5 个请求
net = SyncNet(rate_limit=5)

# 精细配置
net = SyncNet(rate_limit=RateLimitConfig(
    rate=10,                            # 全局每秒 10 个
    per_domain={
        "api.example.com": 2,           # 特定域名每秒 2 个
        "slow.example.com": RateLimitConfig(rate=1),
    },
))
可选依赖

速率限制功能需要额外安装:

pip install hs-net[sp]

concurrency

限制最大并发数(异步场景下特别有用):

concurrency.py
# 最多同时 10 个请求
async with Net(concurrency=10) as net:
    tasks = [net.get(url) for url in urls]
    results = await asyncio.gather(*tasks)

engine_options

透传给底层引擎的配置:

engine_options.py
# httpx: 关闭 HTTP/2
net = SyncNet(engine="httpx", engine_options={"http2": False})

# curl_cffi: 自定义浏览器指纹
net = SyncNet(engine="curl_cffi", engine_options={
    "impersonate": "chrome",
})

三级配置覆盖

override.py
from hs_net import NetConfig, SyncNet

# 第 1 级:NetConfig 全局默认
config = NetConfig(timeout=30, retries=5, user_agent="chrome")

# 第 2 级:构造函数覆盖
with SyncNet(config=config, timeout=15) as net:
    # timeout=15(构造函数覆盖了 config 的 30)
    # retries=5(继承 config)
    # user_agent="chrome"(继承 config)

    # 第 3 级:请求级覆盖
    resp = net.get("https://example.com", timeout=5)
    # timeout=5(请求级覆盖了构造函数的 15)

headers 和 cookies 合并

headers 和 cookies 采用合并而非覆盖策略:

merge.py
config = NetConfig(headers={"X-Global": "1"})

with SyncNet(config=config, headers={"X-Instance": "2"}) as net:
    resp = net.get("https://example.com", headers={"X-Request": "3"})
    # 实际 headers 包含:
    # X-Global: 1(来自 config)
    # X-Instance: 2(来自构造函数)
    # X-Request: 3(来自请求参数)

同名 key 以更高优先级的值为准。

自定义配置

NetConfig 使用 frozen=True(不可变),不支持继承覆盖。如需团队统一配置,直接实例化即可:

team_config.py
from hs_net import NetConfig, EngineEnum, DEFAULT_USER_AGENT, Net, SyncNet

# 团队统一配置
my_config = NetConfig(
    engine=EngineEnum.CURL_CFFI,
    retries=5,
    user_agent="chrome",
    verify=False,
)

# 异步
async with Net(config=my_config) as net:
    resp = await net.get("https://example.com")

# 同步
with SyncNet(config=my_config) as net:
    resp = net.get("https://example.com")