stream抓包+推送phone实战

最近需要办理某个业务,发现天河区的余号一直为0。突然想到前阵子看过一篇文章,作者在叮咚上一直抢不到菜。通过抓包获取小程序的接口请求数据,然后定时去调用这个接口,判断有菜就自动发推送到手机。于是,周五晚上我也捣鼓了几个小时。发现也可以实现这种半自动化的功能。

下载安装抓包工具

首先,需要通过抓包工具获取小程序的api接口请求数据
我用的是抓包工具是手机app:stream。(在appstore直接下载)
默认安装后是无法抓取 https 类型的,需要在设置里进行相关配置:

如果您要抓取 HTTPS 的请求,需要先启动抓包,然后安装 CA 证书后。
*去设置-通用-关于-证书信任设置 里信任 CA,才可以查看请求的内容。

总之要点击进去“https抓包”,根据提示开启证书信任。

开始抓包

一切设置好后,即可点击“开始抓包”。
然后就是去点击小程序,访问接口。接口访问成功后,停止抓包。顺便把证书信任关闭,不然觉得心慌慌的。
从抓到的包中找到对应的api,然后点击"获取cURL命令"。把请求数据全部复制通过postman的import命令导入,即可在postman请求。

stream抓包+推送phone实战_第1张图片
stream抓包+推送phone实战_第2张图片
stream抓包+推送phone实战_第3张图片

postman的另一个利器,就是能生成各个语言的curl请求。我这里生成go请求:
stream抓包+推送phone实战_第4张图片

手机推送

接下来就是要推送。这个我使用的是苹果手机app:Bark。Bark是一个开发者的专属推送工具,免费、稳定,在 appleStore 中下载 。
步骤很简单。就是bark会自动提供一个url给你,通过get请求调用一下这个url即可推送到i你的手机。
在这里插入图片描述
最后就是在服务器定时执行这个脚本即可。建议不要太频繁,而且提示有余号后,就退出这个程序(利用go的log.Fatalf)。不然一直推送到你手机,很烦。

参考代码

package main

import (
    "fmt"
    "go_card/card"
    "log"
    "time"
)

func main() {
    //周期性定时器(Ticker)
    //每隔n分钟执行一次。第一次执行就要等待n分钟。有毒。
    ticker := time.NewTicker(5 * time.Minute)
    defer ticker.Stop()

    for range ticker.C {
        doSelect()
    }
}

func doSelect() {
    //调用获取广州各区的预约余额
    num, err := card.SelectAreaCount()
    //约定-10086是错误码
    if err != nil {
        log.Fatalf("请求接口失败:%v\n", err)
    }
    log.Printf("本次请求获取到的天河区预约余额数量:%d\n", num)

    if num > 0 {
        s := fmt.Sprintf("有余号有%d个,赶紧去抢!", num)
        log.Println(s)
        url := "https://你的Bark专属url/" + s
        //发送推送
        err := card.SendToPhone(url)
        if err != nil {
            log.Fatalf("发送短信失败:%v\n", err)
        }
        //这里Fatalf会调用os.Exit(1)使整个程序停止.即退出定时器
        log.Fatalf("发送短信通知成功:%v,共有余号:%d\n", err, num)
    }
}

package card

import (
    "encoding/json"
    "errors"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

const err_code = -10086

func SelectAreaCount() (int, error) {

    url := "小程序api"
    method := "GET"

    client := &http.Client{}
    req, err := http.NewRequest(method, url, nil)

    if err != nil {
        return err_code, err
    }
 	//为了隐私,这里省略一堆的header头部
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept-Encoding", "gzip, deflate, br")

    res, err := client.Do(req)
    if err != nil {
        return err_code, err
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return err_code, err
    }
    type AreaData struct {
        Code  int
        Count map[string]int
    }

    var areaData AreaData
    err = json.Unmarshal(body, &areaData)
    if err != nil {
        return err_code, err
    }
    //记录获取到的数据到日志(输出到日志,带有日期格式)
    log.Printf("本次请求获取到的广州各区的预约余额:%v\n", areaData)

    if areaData.Code != 200 {
        return err_code, err
    }

    v, ok := areaData.Count["天河区"]
    if !ok {
        return err_code, errors.New("不存在天河区")
    }
    return v, nil
}

func SendToPhone(url string) error {
    method := "GET"
    client := &http.Client{}
    req, err := http.NewRequest(method, url, nil)
    res, err := client.Do(req)
    if err != nil {
        return err
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return err
    }
    fmt.Println(string(body))
    return nil
}

你可能感兴趣的:(golang,工具,抓包,postman,golang)