You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用requests模块登录需提交非常规POST payload的grpc-web站点

解决方案

问题本质

这个站点的登录接口使用的是gRPC-Web + Protobuf协议,你抓包看到的乱码payload是Protobuf序列化后的二进制数据,不是常规的键值对格式,因此不能直接用Python字典构造payload。

具体操作步骤

  • 第一步:获取接口对应的Protobuf定义文件(.proto后缀)
    你要请求的接口路径是/checkout.CheckoutV1/logInWithEmail,对应的proto文件可以从站点前端打包的JS源码中检索checkout.CheckoutV1关键字获取,文件中会明确定义登录请求的结构体,结构参考如下:
    syntax = "proto3";
    package checkout;
    
    service CheckoutV1 {
      rpc logInWithEmail(LogInWithEmailRequest) returns (LogInWithEmailResponse);
    }
    
    message LogInWithEmailRequest {
      string email = 1;
      string password = 2;
      // 其他可选字段根据实际proto定义补充
    }
    
    message LogInWithEmailResponse {
      // 响应字段根据实际proto定义补充
    }
    
  • 第二步:编译proto文件生成Python调用代码
    先安装依赖包:
    pip install grpcio grpcio-tools
    
    执行编译命令,假设你的proto文件命名为checkout.proto:
    python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. checkout.proto
    
    执行后会生成checkout_pb2.py和checkout_pb2_grpc.py两个可用的Python文件。
  • 第三步:构造符合gRPC-Web规范的payload
    gRPC-Web的请求有固定帧结构:1字节压缩标志位 + 4字节大端序的Protobuf数据长度 + 序列化后的Protobuf二进制数据。
  • 第四步:修改登录请求代码
    参考代码如下:
    import requests
    import struct
    import checkout_pb2
    
    start_url = 'https://www.aboutyou.cz/'
    post_link = 'https://grips-web.aboutyou.com/checkout.CheckoutV1/logInWithEmail'
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
        'Content-Type': 'application/grpc-web+proto',
        'Origin': 'https://www.aboutyou.cz',
        'Referer': 'https://www.aboutyou.cz/',
        'X-Grpc-Web': '1'
    }
    
    with requests.Session() as s:
        # 先访问首页拿到Cloudflare等必要Cookie
        s.get(start_url)
        s.headers.update(headers)
        
        # 填充登录参数
        login_req = checkout_pb2.LogInWithEmailRequest()
        login_req.email = "你的实际登录邮箱"
        login_req.password = "你的实际登录密码"
        
        # 序列化Protobuf数据
        proto_data = login_req.SerializeToString()
        # 构造gRPC-Web帧头:1字节0表示未压缩 + 4字节大端序的Protobuf数据长度
        frame_header = struct.pack('>BI', 0, len(proto_data))
        # 拼接得到最终请求payload
        payload = frame_header + proto_data
        
        # 发送登录请求
        r = s.post(post_link, data=payload)
        print("请求状态码:", r.status_code)
        
        # 如需解析响应,先去掉前5字节的响应帧头,再用响应类反序列化
        if r.status_code == 200:
            resp_proto = r.content[5:]
            login_resp = checkout_pb2.LogInWithEmailResponse()
            login_resp.ParseFromString(resp_proto)
            print("登录响应:", login_resp)
    

注意事项

  • 如果请求被Cloudflare拦截,需要先通过Cloudflare人机验证拿到有效的__cf_bm等Cookie后再发送登录请求,也可以使用undetected-chromedriver等工具绕过反爬检测。
  • 请确保你获取的proto文件定义和站点当前使用的版本一致,否则会出现序列化数据不匹配、请求失败的问题。

内容的提问来源于stack exchange,提问作者MITHU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 12:06:04