V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
winterssy
V2EX  ›  分享创造

可能是最像 requests 的 Golang 网络请求库

  •  
  •   winterssy · 2019-12-04 21:36:03 +08:00 · 5192 次点击
    这是一个创建于 1566 天前的主题,其中的信息可能已经有所发展或是发生改变。

    sreq 是一个简单、易用以及并发安全的 Golang 网络请求库,灵感来自 Python requestssreq 提供了 requests 风格的 API,让你可以像使用 requests 那样轻松高效地使用 net/http

    发送请求

    • requests
    resp = requests.get('http://httpbin.org/get')
    
    • sreq
    resp := sreq.Get("http://httpbin.org/get")
    

    传递 URL 参数

    • requests
    payload = {
        'key1': 'value1',
        'key2': 'value2',
    }
    resp = requests.get('http://httpbin.org/get', params=payload)
    
    • sreq
    payload := sreq.Params{
        "key1": "value1",
        "key2": "value2",
    }
    resp := sreq.Get("http://httpbin.org/get", sreq.WithQuery(payload))
    

    响应内容

    • requests
    data = requests.get('http://httpbin.org/get').text
    
    • sreq
    // ignore error
    data, _ := sreq.Get("http://httpbin.org/get").Text()
    

    二进制响应内容

    • requests
    data = requests.get('http://httpbin.org/get').content
    
    • sreq
    // ignore error
    data, _ := sreq.Get("http://httpbin.org/get").Content()
    

    JSON 响应内容

    • requests
    data = requests.get('http://httpbin.org/get').json()
    
    • sreq
    data := make(map[string]interface{})
    // ignore error
    _ = sreq.Get("http://httpbin.org/get").JSON(&data)
    

    原始响应内容

    • requests
    data = requests.get('http://httpbin.org/get', stream=True).raw
    
    • sreq
    // ignore error
    data, _ := sreq.Get("http://httpbin.org/get").Raw()
    

    定制请求头

    • requests
    headers = {
        'Referer': 'https://www.google.com',
    }
    resp = requests.get('http://httpbin.org/get', headers=headers)
    
    • sreq
    headers := sreq.Headers{
        "Referer": "https://www.google.com",
    }
    resp := sreq.Get("http://httpbin.org/get", sreq.WithHeaders(headers))
    

    更加复杂的 POST 请求

    • requests
    payload = {
        'key1': 'value1',
        'key2': 'value2',
    }
    resp = requests.post('http://httpbin.org/post', data=payload)
    
    • sreq
    payload := sreq.Form{
        "key1": "value1",
        "key2": "value2",
    }
    resp := sreq.Post("http://httpbin.org/post", sreq.WithForm(payload))
    

    上传文件

    • requests
    files = {
        'file': open('report.xls', 'rb'),
    }
    resp = requests.post('http://httpbin.org/post', files=files)
    
    • sreq
    files := sreq.Files{
        "file": "report.xls",
    }
    resp := sreq.Post("http://httpbin.org/post", sreq.WithFiles(files))
    

    发送 Cookies

    • requests
    cookies = {
        'name1': 'value1',
    }
    resp = requests.get("http://httpbin.org/get", cookies=cookies)
    
    • sreq
    cookie := &http.Cookie{
        Name:  "name1",
        Value: "value1",
    }
    resp := sreq.Get("http://httpbin.org/get", sreq.WithCookies(cookie))
    

    响应 Cookies

    • requests
    cookies = requests.get('https://www.xiami.com').cookies
    
    • sreq
    // ignore error
    cookies, _ := sreq.
        Get("https://www.xiami.com").
        Cookies()
    

    更多用法可参阅:中文 Wiki 或者 API 文档

    备注:sreq 不提供后向兼容保证,推荐在个人项目中使用。

    19 条回复    2019-12-07 18:24:20 +08:00
    io123
        1
    io123  
       2019-12-04 22:20:55 +08:00 via Android
    前排支持大佬
    ArJun
        2
    ArJun  
       2019-12-04 22:22:56 +08:00
    感觉用 go 的人越来越多了
    co3site
        3
    co3site  
       2019-12-04 22:24:46 +08:00 via Android
    看来得学学 Go 了
    alexkkaa
        4
    alexkkaa  
       2019-12-04 22:50:19 +08:00 via Android
    requests 的强大不仅在于好用。而在于它对 http 标准的完美兼容和完善实现。再说动态语言的方便是静态语言无法比拟的
    winterssy
        5
    winterssy  
    OP
       2019-12-04 23:04:09 +08:00
    @alexkkaa #4 所以没法完全复刻,只是 Golang 的 `net/http` 实在太难用了,要不然也不用重复造轮子。requests 是好用,但并不强大,在并发场景要逊色很多,aiohttp 倒不错,语法跟 requests 也很像。
    ZSeptember
        6
    ZSeptember  
       2019-12-05 12:01:43 +08:00
    不错,很喜欢 option 这种设计,不知道有没有 middleware 这种机制,可以参考下 resty
    superrichman
        7
    superrichman  
       2019-12-05 13:06:35 +08:00 via iPhone
    虽然我不用 go,但是提个问题:上传文件支持直接用内存里的数据吗?我看参数只有一个文件名。
    winterssy
        8
    winterssy  
    OP
       2019-12-05 13:20:49 +08:00
    @superrichman #7 不是哈,是分块上传的,并且用了 os.Pipe,内存占用也比较低
    winterssy
        9
    winterssy  
    OP
       2019-12-05 13:24:50 +08:00
    @ZSeptember #6 我看了下,resty 的 middleware 相当于请求 /响应拦截器,后续会加上,能否针对此功能提些建议?
    superrichman
        10
    superrichman  
       2019-12-05 15:32:14 +08:00 via iPhone
    @winterssy 可能我没表述清楚。举个例子吧,比如我用程序读取了一个 excel 模版文件到内存里,然后往 excel 里面添加一些数据,这个时候我要把修改后的数据 post 出去但是不想在硬盘上写个临时文件。
    winterssy
        11
    winterssy  
    OP
       2019-12-05 15:43:42 +08:00
    @superrichman #10 sreq 支持这样的功能,只不过由另外的 API 提供,而且不管是何种方式 sreq 都不会写临时文件。
    winterssy
        12
    winterssy  
    OP
       2019-12-05 16:32:44 +08:00
    @ZSeptember #6 我在开发分支增加了你说的 middleware 机制,不知是否是你想要的?

    <script src="https://gist.github.com/winterssy/098c1097294552c490699c4aa6e51b50.js"></script>
    wnanbei
        13
    wnanbei  
       2019-12-06 10:12:19 +08:00
    params 这些参数用 map[string]string 的话,是无法处理多个同名参数的问题的
    winterssy
        14
    winterssy  
    OP
       2019-12-06 11:09:22 +08:00
    @wnanbei #13 感谢反馈,我已在最新的 commit 中修正此问题,这种情况下你只要调用多次 `sreq.WithQuery` 或者 `sreq.WithForm` 即可。
    ZSeptember
        15
    ZSeptember  
       2019-12-07 11:02:49 +08:00
    @winterssy middleware 差不多就是这样的了。不过,你还有些东西没考虑到,压缩之类的。
    winterssy
        16
    winterssy  
    OP
       2019-12-07 14:13:41 +08:00
    @ZSeptember #15 如果你不设置 Accept-Encoding 请求头的话,net/http 会自动解压缩,不知你指的场景是什么
    ZSeptember
        17
    ZSeptember  
       2019-12-07 14:36:41 +08:00
    @winterssy 就是这个场景。这个,你就不能假定用户不设置这个 header 了。
    abmin521
        18
    abmin521  
       2019-12-07 14:54:57 +08:00
    在搞一个 httpie 的 cli?
    winterssy
        19
    winterssy  
    OP
       2019-12-07 18:24:20 +08:00   ❤️ 1
    @ZSeptember #17 v0.3.0 已加上。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5592 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 05:50 · PVG 13:50 · LAX 22:50 · JFK 01:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.