├── .gitignore ├── README.md ├── all └── all.go ├── app ├── 360doc.go ├── 360search.go ├── acfun.go ├── baidu.go ├── bilibili.go ├── cctv.go ├── csdn.go ├── dongqiudi.go ├── douban.go ├── douyin.go ├── github.go ├── guojiadili.go ├── history.go ├── hupu.go ├── ithome.go ├── lishipin.go ├── nanfangzhoumo.go ├── pengpai.go ├── qqnews.go ├── quark.go ├── renmin.go ├── shaoshupai.go ├── sougou.go ├── souhu.go ├── toutiao.go ├── v2ex.go ├── wangyinews.go ├── weibo.go ├── xinjingbao.go └── zhihu.go ├── go.mod ├── go.sum ├── main.go └── utils └── utils.go /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 目前包含30个app,不断添加中 2 | ## 代码很简单粗暴,以后再精简优化 3 | 4 | + 360搜索 5 | + 哔哩哔哩 6 | + AcFun 7 | + CSDN 8 | + 懂球帝 9 | + 豆瓣 10 | + 抖音 11 | + GitHub 12 | + 国家地理 13 | + 历史上的今天 14 | + 虎扑 15 | + IT之家 16 | + 梨视频 17 | + 澎湃新闻 18 | + 腾讯新闻 19 | + 少数派 20 | + 搜狗 21 | + 今日头条 22 | + V2EX 23 | + 网易新闻 24 | + 微博 25 | + 新京报 26 | + 知乎 27 | + 夸克 28 | + 搜狐 29 | + 百度 30 | + 人民网 31 | + 南方周末 32 | + 360doc 33 | + CCTV新闻 34 | 35 | ## 运行 36 | 37 | `go run main.go` 38 | 39 | 默认端口为1111,可以自己改。 40 | 41 | 浏览器打开`ip:1111` 42 | 43 | 具体路径看`main.go`中的路由表 44 | 45 | 比如访问百度的热搜就是:`ip:1111/baidu` 46 | 47 | 查看全部app的热搜为`ip:1111/all` 48 | 49 | 建议`go build`为可执行文件。 -------------------------------------------------------------------------------- /all/all.go: -------------------------------------------------------------------------------- 1 | package all 2 | 3 | import ( 4 | "api/app" 5 | "fmt" 6 | "sync" 7 | ) 8 | 9 | func All() map[string]interface{} { 10 | // 定义一个函数列表,方便循环调用 11 | funcs := map[string]func() map[string]interface{}{ 12 | "360搜索": app.Search360, 13 | "哔哩哔哩": app.Bilibili, 14 | "AcFun": app.Acfun, 15 | "CSDN": app.CSDN, 16 | "懂球帝": app.Dongqiudi, 17 | "豆瓣": app.Douban, 18 | "抖音": app.Douyin, 19 | "GitHub": app.Github, 20 | "国家地理": app.Guojiadili, 21 | "历史上的今天": app.History, 22 | "虎扑": app.Hupu, 23 | "IT之家": app.Ithome, 24 | "梨视频": app.Lishipin, 25 | "澎湃新闻": app.Pengpai, 26 | "腾讯新闻": app.Qqnews, 27 | "少数派": app.Shaoshupai, 28 | "搜狗": app.Sougou, 29 | "今日头条": app.Toutiao, 30 | "V2EX": app.V2ex, 31 | "网易新闻": app.WangyiNews, 32 | "微博": app.WeiboHot, 33 | "新京报": app.Xinjingbao, 34 | "知乎": app.Zhihu, 35 | "夸克": app.Quark, 36 | "搜狐": app.Souhu, 37 | "百度": app.Baidu, 38 | "人民网": app.Renminwang, 39 | "南方周末": app.Nanfangzhoumo, 40 | "360doc": app.Doc360, 41 | "CCTV新闻": app.CCTV, 42 | } 43 | 44 | allResult := make(map[string]interface{}) 45 | 46 | // 使用并发来调用各个函数 47 | var wg sync.WaitGroup 48 | var mu sync.Mutex 49 | 50 | for key, fn := range funcs { 51 | wg.Add(1) 52 | go func(k string, f func() map[string]interface{}) { 53 | defer wg.Done() 54 | result := f() 55 | 56 | // 检查是否调用成功(假设成功时 code 为 200) 57 | if result["code"] == 200 { 58 | mu.Lock() 59 | allResult[k] = result["obj"] 60 | mu.Unlock() 61 | } 62 | // 如果失败,则不添加到 allResult 中 63 | }(key, fn) 64 | } 65 | 66 | wg.Wait() 67 | fmt.Println(len(allResult)) 68 | return map[string]interface{}{ 69 | "code": 200, 70 | "obj": allResult, 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/360doc.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Doc360() map[string]interface{} { 10 | url := "http://www.360doc.com/" 11 | resp, err := http.Get(url) 12 | utils.HandleError(err, "http.Get") 13 | defer resp.Body.Close() 14 | pageBytes, err := io.ReadAll(resp.Body) 15 | utils.HandleError(err, "io.ReadAll") 16 | 17 | pattern := `
(?:)?(.*?)
` 18 | matched := utils.ExtractMatches(string(pageBytes), pattern) 19 | 20 | var obj []map[string]interface{} 21 | for index, item := range matched { 22 | obj = append(obj, map[string]interface{}{ 23 | "index": index + 1, 24 | "title": item[2], 25 | "url": item[1], 26 | }) 27 | } 28 | api := map[string]interface{}{ 29 | "code": 200, 30 | "message": "360doc", 31 | "icon": "http://www.360doc.com/favicon.ico", // 16 x 16 32 | "obj": obj, 33 | } 34 | return api 35 | } 36 | -------------------------------------------------------------------------------- /app/360search.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "strconv" 10 | ) 11 | 12 | type search360Item struct { 13 | LongTitle string `json:"long_title"` 14 | Title string `json:"title"` 15 | Score string `json:"score"` 16 | Rank string `json:"rank"` 17 | } 18 | 19 | func Search360() map[string]interface{} { 20 | url := "https://ranks.hao.360.com/mbsug-api/hotnewsquery?type=news&realhot_limit=50" 21 | resp, err := http.Get(url) 22 | utils.HandleError(err, "http.Get error") 23 | defer resp.Body.Close() 24 | // 2.读取页面内容 25 | pageBytes, err := io.ReadAll(resp.Body) 26 | utils.HandleError(err, "io.ReadAll error") 27 | 28 | var resultSlice []search360Item 29 | err = json.Unmarshal([]byte(string(pageBytes)), &resultSlice) 30 | utils.HandleError(err, "json.Unmarshal error") 31 | 32 | var obj []map[string]interface{} 33 | for _, item := range resultSlice { 34 | title := item.Title 35 | if item.LongTitle != "" { 36 | title = item.LongTitle 37 | } 38 | hot, err := strconv.ParseFloat(item.Score, 64) 39 | utils.HandleError(err, "strconv.ParseFloat") 40 | 41 | obj = append(obj, map[string]interface{}{ 42 | "index": item.Rank, 43 | "title": title, 44 | "hotValue": fmt.Sprintf("%.1f万", hot/10000), 45 | "url": "https://www.so.com/s?q=" + title, 46 | }) 47 | } 48 | api := map[string]interface{}{ 49 | "code": 200, 50 | "message": "夸克", 51 | "icon": "https://ss.360tres.com/static/121a1737750aa53d.ico", 52 | "obj": obj, 53 | } 54 | return api 55 | } 56 | -------------------------------------------------------------------------------- /app/acfun.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | type acfunResponse struct { 11 | RankList []acfunData `json:"rankList"` 12 | } 13 | type acfunData struct { 14 | Title string `json:"contentTitle"` 15 | URL string `json:"shareUrl"` 16 | } 17 | 18 | func Acfun() map[string]interface{} { 19 | url := "https://www.acfun.cn/rest/pc-direct/rank/channel?channelId=&subChannelId=&rankLimit=30&rankPeriod=DAY" 20 | // 创建一个自定义请求 21 | req, err := http.NewRequest("GET", url, nil) 22 | utils.HandleError(err, "http.NewRequest") 23 | // 设置 Headers 24 | req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36") 25 | resp, err := http.DefaultClient.Do(req) 26 | utils.HandleError(err, "http.DefaultClient.Do") 27 | defer resp.Body.Close() 28 | 29 | pageBytes, err := io.ReadAll(resp.Body) 30 | utils.HandleError(err, "io.ReadAll error") 31 | var resultMap acfunResponse 32 | err = json.Unmarshal(pageBytes, &resultMap) 33 | utils.HandleError(err, "json.Unmarshal error") 34 | 35 | var obj []map[string]interface{} 36 | 37 | for index, item := range resultMap.RankList { 38 | obj = append(obj, map[string]interface{}{ 39 | "index": index + 1, 40 | "title": item.Title, 41 | "url": item.URL, 42 | }) 43 | } 44 | api := map[string]interface{}{ 45 | "code": 200, 46 | "message": "AcFun", 47 | "icon": "https://cdn.aixifan.com/ico/favicon.ico", // 32 x 32 48 | "obj": obj, 49 | } 50 | 51 | return api 52 | } 53 | -------------------------------------------------------------------------------- /app/baidu.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | "strings" 8 | ) 9 | 10 | func Baidu() map[string]interface{} { 11 | url := "https://top.baidu.com/board?tab=realtime" 12 | resp, err := http.Get(url) 13 | utils.HandleError(err, "http.Get") 14 | defer resp.Body.Close() 15 | pageBytes, err := io.ReadAll(resp.Body) 16 | utils.HandleError(err, "io.ReadAll") 17 | pattern := `(.*?)\s*([^<]+)\s*<\/span>\s*([^<]+)<\/a>\s*<\/h2>\s*\s*([^<]+)\s*<\/p>` 19 | matched := utils.ExtractMatches(string(pageBytes), pattern) 20 | 21 | var obj []map[string]interface{} 22 | for index, item := range matched { 23 | trimed := strings.ReplaceAll(strings.TrimSpace(item[1])+strings.TrimSpace(item[2]), " ", "") 24 | obj = append(obj, map[string]interface{}{ 25 | "index": index + 1, 26 | "title": trimed, 27 | "desc": strings.TrimSpace(item[3]), 28 | "url": "https://github.com/" + trimed, 29 | }) 30 | } 31 | api := map[string]interface{}{ 32 | "code": 200, 33 | "message": "GitHub", 34 | "icon": "https://github.githubassets.com/favicons/favicon.png", // 32 x 32 35 | "obj": obj, 36 | } 37 | return api 38 | } 39 | -------------------------------------------------------------------------------- /app/guojiadili.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Guojiadili() map[string]interface{} { 10 | url := "http://www.dili360.com/" 11 | resp, err := http.Get(url) 12 | utils.HandleError(err, "http.Get") 13 | defer resp.Body.Close() 14 | pageBytes, err := io.ReadAll(resp.Body) 15 | utils.HandleError(err, "io.ReadAll") 16 | pattern := `
  • \s*\d*\s*

    (.*?)` 17 | matched := utils.ExtractMatches(string(pageBytes), pattern) 18 | 19 | var obj []map[string]interface{} 20 | for index, item := range matched { 21 | obj = append(obj, map[string]interface{}{ 22 | "index": index + 1, 23 | "title": item[2], 24 | "url": "http://www.dili360.com" + item[1], 25 | }) 26 | } 27 | api := map[string]interface{}{ 28 | "code": 200, 29 | "message": "国家地理", 30 | "icon": "http://www.dili360.com/favicon.ico", // 32 x 32 31 | "obj": obj, 32 | } 33 | return api 34 | } 35 | -------------------------------------------------------------------------------- /app/history.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "strings" 10 | "time" 11 | 12 | "golang.org/x/net/html" 13 | ) 14 | 15 | func stripHTML(htmlString string) string { 16 | // 使用 html.Parse 解析 HTML 字符串 17 | doc, err := html.Parse(strings.NewReader(htmlString)) 18 | if err != nil { 19 | fmt.Println("解析HTML时出错:", err) 20 | return htmlString 21 | } 22 | 23 | // 使用一个 buffer 保存结果 24 | var result strings.Builder 25 | 26 | // 定义一个递归函数来遍历 HTML 树 27 | var visit func(n *html.Node) 28 | visit = func(n *html.Node) { 29 | // 如果当前节点是文本节点,将文本内容追加到结果中 30 | if n.Type == html.TextNode { 31 | result.WriteString(n.Data) 32 | } 33 | // 递归处理子节点 34 | for c := n.FirstChild; c != nil; c = c.NextSibling { 35 | visit(c) 36 | } 37 | } 38 | 39 | // 调用递归函数开始遍历 HTML 树 40 | visit(doc) 41 | 42 | // 返回结果的字符串形式 43 | return result.String() 44 | } 45 | 46 | func History() map[string]interface{} { 47 | currentTime := time.Now() 48 | month := fmt.Sprintf("%02d", currentTime.Month()) 49 | day := fmt.Sprintf("%02d", currentTime.Day()) 50 | url := "https://baike.baidu.com/cms/home/eventsOnHistory/" + fmt.Sprint(month) + ".json" 51 | resp, err := http.Get(url) 52 | utils.HandleError(err, "http.Get") 53 | defer resp.Body.Close() 54 | pageBytes, err := io.ReadAll(resp.Body) 55 | utils.HandleError(err, "io.ReadAll error") 56 | var resultMap map[string]interface{} 57 | err = json.Unmarshal(pageBytes, &resultMap) 58 | utils.HandleError(err, "io.json.Unmarshal error") 59 | 60 | date := fmt.Sprintf("%v%v", month, day) 61 | dateList := resultMap[month].(map[string]interface{})[date] 62 | 63 | api := make(map[string]interface{}) 64 | api["code"] = 200 65 | api["message"] = "历史上的今天" 66 | 67 | var obj []map[string]interface{} 68 | for index, item := range dateList.([]interface{}) { 69 | result := make(map[string]interface{}) 70 | result["index"] = index + 1 71 | result["title"] = stripHTML(item.(map[string]interface{})["title"].(string)) 72 | result["url"] = item.(map[string]interface{})["link"] 73 | obj = append(obj, result) 74 | } 75 | api["obj"] = obj 76 | api["icon"] = "https://baike.baidu.com/favicon.ico" // 64 x 64 77 | return api 78 | } 79 | -------------------------------------------------------------------------------- /app/hupu.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Hupu() map[string]interface{} { 10 | url := "https://www.hupu.com/" 11 | resp, err := http.Get(url) 12 | // fmt.Println(resp) 13 | utils.HandleError(err, "http.Get") 14 | defer resp.Body.Close() 15 | pageBytes, err := io.ReadAll(resp.Body) 16 | utils.HandleError(err, "io.ReadAll") 17 | pattern := `]+>\s*]+>\s*]+>\d+\s*]+>(.*?)` 18 | matches := utils.ExtractMatches(string(pageBytes), pattern) 19 | 20 | var obj []map[string]interface{} 21 | for index, item := range matches { 22 | obj = append(obj, map[string]interface{}{ 23 | "index": index + 1, 24 | "title": item[2], 25 | "url": item[1], 26 | }) 27 | } 28 | api := map[string]interface{}{ 29 | "code": 200, 30 | "message": "虎扑", 31 | "icon": "https://www.hupu.com/favicon.ico", // 32 x 32 32 | "obj": obj, 33 | } 34 | return api 35 | } 36 | -------------------------------------------------------------------------------- /app/ithome.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Ithome() map[string]interface{} { 10 | url := "https://m.ithome.com/rankm/" 11 | resp, err := http.Get(url) 12 | utils.HandleError(err, "http.Get") 13 | defer resp.Body.Close() 14 | pageBytes, err := io.ReadAll(resp.Body) 15 | utils.HandleError(err, "io.ReadAll") 16 | pattern := `]*>.*?(.*?)

    ` 17 | matches := utils.ExtractMatches(string(pageBytes), pattern) 18 | 19 | var obj []map[string]interface{} 20 | for index, item := range matches[:12] { 21 | obj = append(obj, map[string]interface{}{ 22 | "index": index + 1, 23 | "title": item[2], 24 | "url": item[1], 25 | }) 26 | } 27 | api := map[string]interface{}{ 28 | "code": 200, 29 | "message": "IT之家", 30 | "icon": "https://www.ithome.com/favicon.ico", // 32 x 32 31 | "obj": obj, 32 | } 33 | return api 34 | } 35 | -------------------------------------------------------------------------------- /app/lishipin.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | func Lishipin() map[string]interface{} { 11 | url := "https://www.pearvideo.com/popular" 12 | resp, err := http.Get(url) 13 | utils.HandleError(err, "http.Get") 14 | defer resp.Body.Close() 15 | pageBytes, err := io.ReadAll(resp.Body) 16 | utils.HandleError(err, "io.ReadAll") 17 | 18 | pattern := `\s*(.*?)

    \s*(.*?)

    ` 19 | matched := utils.ExtractMatches(string(pageBytes), pattern) 20 | 21 | var obj []map[string]interface{} 22 | for index, item := range matched { 23 | obj = append(obj, map[string]interface{}{ 24 | "index": index + 1, 25 | "title": item[2], 26 | "url": "https://www.pearvideo.com/" + fmt.Sprint(item[1]), 27 | "desc": item[3], 28 | }) 29 | } 30 | api := map[string]interface{}{ 31 | "code": 200, 32 | "message": "梨视频", 33 | "icon": "https://page.pearvideo.com/webres/img/logo.png", // 76 x 98 34 | "obj": obj, 35 | } 36 | return api 37 | } 38 | -------------------------------------------------------------------------------- /app/nanfangzhoumo.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "io" 7 | "net/http" 8 | "strconv" 9 | ) 10 | 11 | type nfResponse struct { 12 | NfzmData nfData `json:"data"` 13 | } 14 | type nfData struct { 15 | HotContents []contents `json:"hot_contents"` 16 | } 17 | type contents struct { 18 | Title string `json:"subject"` 19 | ID float64 `json:"id"` 20 | } 21 | 22 | func Nanfangzhoumo() map[string]interface{} { 23 | url := "https://www.infzm.com/hot_contents?format=json" 24 | resp, err := http.Get(url) 25 | utils.HandleError(err, "http.Get") 26 | defer resp.Body.Close() 27 | // 2.读取页面内容 28 | pageBytes, err := io.ReadAll(resp.Body) 29 | utils.HandleError(err, "io.ReadAll") 30 | var resultMap nfResponse 31 | _ = json.Unmarshal(pageBytes, &resultMap) 32 | 33 | wordList := resultMap.NfzmData.HotContents 34 | 35 | var obj []map[string]interface{} 36 | for index, item := range wordList { 37 | obj = append(obj, map[string]interface{}{ 38 | "index": index + 1, 39 | "title": item.Title, 40 | "url": "https://www.infzm.com/contents/" + strconv.FormatFloat(item.ID, 'f', -1, 64), 41 | }) 42 | } 43 | api := map[string]interface{}{ 44 | "code": 200, 45 | "message": "南方周末", 46 | "icon": "https://www.infzm.com/favicon.ico", // 32 x 32 47 | "obj": obj, 48 | } 49 | return api 50 | } 51 | -------------------------------------------------------------------------------- /app/pengpai.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | type ppResponse struct { 11 | Data ppData `json:"data"` 12 | } 13 | type ppData struct { 14 | HotNews []news `json:"hotNews"` 15 | } 16 | type news struct { 17 | Title string `json:"name"` 18 | ContId string `json:"contId"` 19 | } 20 | 21 | func Pengpai() map[string]interface{} { 22 | url := "https://cache.thepaper.cn/contentapi/wwwIndex/rightSidebar" 23 | resp, err := http.Get(url) 24 | utils.HandleError(err, "http.Get") 25 | defer resp.Body.Close() 26 | pageBytes, err := io.ReadAll(resp.Body) 27 | utils.HandleError(err, "io.ReadAll") 28 | var resultMap ppResponse 29 | _ = json.Unmarshal(pageBytes, &resultMap) 30 | 31 | data := resultMap.Data.HotNews 32 | 33 | var obj []map[string]interface{} 34 | for index, item := range data { 35 | obj = append(obj, map[string]interface{}{ 36 | "index": index + 1, 37 | "title": item.Title, 38 | "url": "https://www.thepaper.cn/newsDetail_forward_" + item.ContId, 39 | }) 40 | } 41 | api := map[string]interface{}{ 42 | "code": 200, 43 | "message": "澎湃新闻", 44 | "icon": "https://www.thepaper.cn/favicon.ico", // 32 x 32 45 | "obj": obj, 46 | } 47 | return api 48 | } 49 | -------------------------------------------------------------------------------- /app/qqnews.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | ) 10 | 11 | type qqResponse struct { 12 | IdList []idListItem `json:"idlist"` 13 | } 14 | 15 | type idListItem struct { 16 | IdsHash string `json:"ids_hash"` 17 | NewsList []newsItem `json:"newslist"` 18 | } 19 | 20 | type newsItem struct { 21 | Title string `json:"title"` 22 | Url string `json:"url"` 23 | Time string `json:"time"` 24 | HotEvent hotEvent `json:"hotEvent"` 25 | } 26 | 27 | type hotEvent struct { 28 | HotScore float64 `json:"hotScore"` 29 | } 30 | 31 | func Qqnews() map[string]interface{} { 32 | url := "https://r.inews.qq.com/gw/event/hot_ranking_list?page_size=51" 33 | resp, err := http.Get(url) 34 | utils.HandleError(err, "http.Get") 35 | defer resp.Body.Close() 36 | pageBytes, err := io.ReadAll(resp.Body) 37 | utils.HandleError(err, "io.ReadAll") 38 | 39 | // 使用结构体解析响应 40 | var result qqResponse 41 | _ = json.Unmarshal(pageBytes, &result) 42 | 43 | // 获取新闻列表数据 44 | newsListData := result.IdList[0].NewsList 45 | 46 | var obj []map[string]interface{} 47 | for index, item := range newsListData { 48 | if index == 0 { 49 | continue 50 | } 51 | hot := item.HotEvent.HotScore / 10000 52 | hotValue := fmt.Sprintf("%.1f万", hot) 53 | 54 | obj = append(obj, map[string]interface{}{ 55 | "index": index, 56 | "title": item.Title, 57 | "url": item.Url, 58 | "time": item.Time, 59 | "hotValue": hotValue, 60 | }) 61 | } 62 | api := map[string]interface{}{ 63 | "code": 200, 64 | "message": "腾讯新闻", 65 | "icon": "https://mat1.gtimg.com/qqcdn/qqindex2021/favicon.ico", // 96 x 96 66 | "obj": obj, 67 | } 68 | return api 69 | } 70 | -------------------------------------------------------------------------------- /app/quark.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "strconv" 10 | ) 11 | 12 | type quarkResponse struct { 13 | Data quarkData `json:"data"` 14 | } 15 | type quarkData struct { 16 | HotNews hotNews `json:"hotNews"` 17 | } 18 | type hotNews struct { 19 | Item []quarkItem `json:"item"` 20 | } 21 | type quarkItem struct { 22 | URL string `json:"url"` 23 | Title string `json:"title"` 24 | HotValue string `json:"hot"` 25 | } 26 | 27 | func Quark() map[string]interface{} { 28 | url := "https://biz.quark.cn/api/trending/ranking/getNewsRanking?modules=hotNews&uc_param_str=dnfrpfbivessbtbmnilauputogpintnwmtsvcppcprsnnnchmicckpgixsnx" 29 | resp, err := http.Get(url) 30 | utils.HandleError(err, "http.Get error") 31 | defer resp.Body.Close() 32 | pageBytes, err := io.ReadAll(resp.Body) 33 | utils.HandleError(err, "io.ReadAll error") 34 | var resultMap quarkResponse 35 | err = json.Unmarshal(pageBytes, &resultMap) 36 | utils.HandleError(err, "json.Unmarshal error") 37 | 38 | data := resultMap.Data.HotNews.Item 39 | obj := make([]map[string]interface{}, 0, len(data)) 40 | 41 | for i, item := range data { 42 | hot, err := strconv.ParseFloat(item.HotValue, 64) 43 | if err != nil { 44 | hot = 0 45 | } 46 | 47 | obj = append(obj, map[string]interface{}{ 48 | "index": i + 1, 49 | "title": item.Title, 50 | "url": item.URL, 51 | "hotValue": fmt.Sprintf("%.1f万", hot/10000), 52 | }) 53 | } 54 | 55 | api := map[string]interface{}{ 56 | "code": 200, 57 | "message": "夸克", 58 | "obj": obj, 59 | "icon": "https://gw.alicdn.com/imgextra/i3/O1CN018r2tKf28YP7ev0fPF_!!6000000007944-2-tps-48-48.png", 60 | } 61 | return api 62 | } 63 | -------------------------------------------------------------------------------- /app/renmin.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Renminwang() map[string]interface{} { 10 | url := "http://www.people.com.cn/GB/59476/index.html" 11 | resp, err := http.Get(url) 12 | utils.HandleError(err, "http.Get") 13 | defer resp.Body.Close() 14 | pageBytes, err := io.ReadAll(resp.Body) 15 | utils.HandleError(err, "io.ReadAll") 16 | 17 | pattern := `
  • (.*?)
  • ` 18 | matched := utils.ExtractMatches(string(pageBytes), pattern) 19 | 20 | var obj []map[string]interface{} 21 | for index, item := range matched { 22 | result := make(map[string]interface{}) 23 | result["index"] = index + 1 24 | result["title"] = item[2] 25 | result["url"] = item[1] 26 | obj = append(obj, result) 27 | } 28 | api := map[string]interface{}{ 29 | "code": 200, 30 | "message": "人民网", 31 | "icon": "http://www.people.com.cn/favicon.ico", // 16 x 16 32 | "obj": obj, 33 | } 34 | return api 35 | } 36 | -------------------------------------------------------------------------------- /app/shaoshupai.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | ) 10 | 11 | type sspResponse struct { 12 | Data []sspData `json:"data"` 13 | } 14 | type sspData struct { 15 | Title string `json:"title"` 16 | ID int `json:"id"` 17 | } 18 | 19 | func Shaoshupai() map[string]interface{} { 20 | url := "https://sspai.com/api/v1/article/tag/page/get?limit=100000&tag=%E7%83%AD%E9%97%A8%E6%96%87%E7%AB%A0" 21 | resp, err := http.Get(url) 22 | utils.HandleError(err, "http.Get") 23 | defer resp.Body.Close() 24 | pageBytes, err := io.ReadAll(resp.Body) 25 | utils.HandleError(err, "io.ReadAll") 26 | var resultMap sspResponse 27 | _ = json.Unmarshal(pageBytes, &resultMap) 28 | 29 | data := resultMap.Data 30 | 31 | var obj []map[string]interface{} 32 | for index, item := range data { 33 | obj = append(obj, map[string]interface{}{ 34 | "index": index + 1, 35 | "title": item.Title, 36 | "url": "https://sspai.com/post/" + fmt.Sprint(item.ID), 37 | }) 38 | } 39 | api := map[string]interface{}{ 40 | "code": 200, 41 | "message": "少数派", 42 | "icon": "https://cdn-static.sspai.com/favicon/sspai.ico", // 64 x 64 43 | "obj": obj, 44 | } 45 | return api 46 | } 47 | -------------------------------------------------------------------------------- /app/sougou.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Sougou() map[string]interface{} { 10 | url := "https://www.sogou.com/web?query=%E6%90%9C%E7%8B%97%E7%83%AD%E6%90%9C" 11 | req, err := http.NewRequest("GET", url, nil) 12 | utils.HandleError(err, "http.NewRequest") 13 | req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36") 14 | resp, err := http.DefaultClient.Do(req) 15 | 16 | utils.HandleError(err, "http.Get") 17 | defer resp.Body.Close() 18 | 19 | pageBytes, err := io.ReadAll(resp.Body) 20 | utils.HandleError(err, "io.ReadAll") 21 | 22 | pattern := `]*>[\s\S]*?

    \s*]*>(.*?)\s*

    [\s\S]*?
    \s*(.*?)` 23 | matched := utils.ExtractMatches(string(pageBytes), pattern) 24 | 25 | var obj []map[string]interface{} 26 | for index, item := range matched { 27 | obj = append(obj, map[string]interface{}{ 28 | "index": index + 1, 29 | "title": item[2], 30 | "url": item[1], 31 | "hotValue": item[3], 32 | }) 33 | } 34 | api := map[string]interface{}{ 35 | "code": 200, 36 | "message": "搜狗", 37 | "icon": "https://www.sogou.com/favicon.ico", // 32 x 32 38 | "obj": obj, 39 | } 40 | return api 41 | } 42 | -------------------------------------------------------------------------------- /app/souhu.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "strconv" 9 | "sync" 10 | ) 11 | 12 | type souhuResponse struct { 13 | Data []newsArticles `json:"newsArticles"` 14 | } 15 | type newsArticles struct { 16 | Title string `json:"title"` 17 | URL string `json:"h5Link"` 18 | Hot string `json:"score"` 19 | } 20 | 21 | func fetchSouhuPage(page int) ([]newsArticles, error) { 22 | url := fmt.Sprintf("https://3g.k.sohu.com/api/channel/hotchart/hotnews.go?p1=NjY2NjY2&page=%d", page) 23 | resp, err := http.Get(url) 24 | if err != nil { 25 | return nil, err 26 | } 27 | defer resp.Body.Close() 28 | 29 | pageBytes, err := io.ReadAll(resp.Body) 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | var resultMap souhuResponse 35 | err = json.Unmarshal(pageBytes, &resultMap) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | return resultMap.Data, nil 41 | } 42 | 43 | func Souhu() map[string]interface{} { 44 | var wordList []newsArticles 45 | var wg sync.WaitGroup 46 | var mutex sync.Mutex 47 | var fetchErrors []error 48 | 49 | // 并发获取两个页面的数据 50 | for i := 1; i <= 2; i++ { 51 | wg.Add(1) 52 | go func(page int) { 53 | defer wg.Done() 54 | data, err := fetchSouhuPage(page) 55 | if err != nil { 56 | mutex.Lock() 57 | fetchErrors = append(fetchErrors, err) 58 | mutex.Unlock() 59 | return 60 | } 61 | mutex.Lock() 62 | wordList = append(wordList, data...) 63 | mutex.Unlock() 64 | }(i) 65 | } 66 | 67 | wg.Wait() 68 | 69 | // 如果有错误发生,返回错误信息 70 | if len(fetchErrors) > 0 { 71 | return map[string]interface{}{ 72 | "code": 500, 73 | "message": fmt.Sprintf("获取数据时出错: %v", fetchErrors), 74 | } 75 | } 76 | 77 | var obj []map[string]interface{} 78 | for index, item := range wordList { 79 | hotValue, err := strconv.ParseFloat(item.Hot, 64) 80 | if err != nil { 81 | hotValue = 0 // 如果解析失败,设置为0 82 | } 83 | obj = append(obj, map[string]interface{}{ 84 | "index": index + 1, 85 | "title": item.Title, 86 | "url": item.URL, 87 | "hotValue": fmt.Sprintf("%.2f万", hotValue), 88 | }) 89 | } 90 | 91 | api := map[string]interface{}{ 92 | "code": 200, 93 | "message": "搜狐新闻", 94 | "icon": "https://3g.k.sohu.com/favicon.ico", // 48 x 48 95 | "obj": obj, 96 | } 97 | return api 98 | } 99 | -------------------------------------------------------------------------------- /app/toutiao.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "strconv" 10 | ) 11 | 12 | type ttResponse struct { 13 | Data []ttData `json:"data"` 14 | } 15 | type ttData struct { 16 | Title string `json:"Title"` 17 | URL string `json:"Url"` 18 | HotValue string `json:"HotValue"` 19 | } 20 | 21 | func Toutiao() map[string]interface{} { 22 | url := "https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc" 23 | resp, err := http.Get(url) 24 | utils.HandleError(err, "http.Get") 25 | defer resp.Body.Close() 26 | pageBytes, err := io.ReadAll(resp.Body) 27 | utils.HandleError(err, "io.ReadAll") 28 | var resultMap ttResponse 29 | _ = json.Unmarshal(pageBytes, &resultMap) 30 | 31 | data := resultMap.Data 32 | 33 | var obj []map[string]interface{} 34 | for index, item := range data { 35 | hot, err := strconv.ParseFloat(item.HotValue, 64) 36 | utils.HandleError(err, "strconv.ParseFloat") 37 | obj = append(obj, map[string]interface{}{ 38 | "index": index + 1, 39 | "title": item.Title, 40 | "url": item.URL, 41 | "hotValue": fmt.Sprintf("%.1f万", hot/10000), 42 | }) 43 | } 44 | api := map[string]interface{}{ 45 | "code": 200, 46 | "message": "今日头条", 47 | "icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/pipieh7nupabozups/toutiao_web_pc/tt-icon.png", // 144 x 144 48 | "obj": obj, 49 | } 50 | return api 51 | } 52 | -------------------------------------------------------------------------------- /app/v2ex.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func V2ex() map[string]interface{} { 10 | url := "https://www.v2ex.com" 11 | resp, err := http.Get(url) 12 | utils.HandleError(err, "http.Get") 13 | defer resp.Body.Close() 14 | pageBytes, err := io.ReadAll(resp.Body) 15 | utils.HandleError(err, "io.ReadAll") 16 | pattern := `\s*(.*?)<\/a>\s*<\/span>` 17 | matched := utils.ExtractMatches(string(pageBytes), pattern) 18 | 19 | var obj []map[string]interface{} 20 | for index, item := range matched { 21 | result := make(map[string]interface{}) 22 | result["index"] = index + 1 23 | result["title"] = item[2] 24 | result["url"] = url + item[1] 25 | obj = append(obj, result) 26 | } 27 | api := map[string]interface{}{ 28 | "code": 200, 29 | "message": "V2EX", 30 | "icon": "https://www.v2ex.com/static/img/icon_rayps_64.png", // 64 x 64 31 | "obj": obj, 32 | } 33 | return api 34 | } 35 | -------------------------------------------------------------------------------- /app/wangyinews.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "strconv" 9 | ) 10 | 11 | func WangyiNews() map[string]interface{} { 12 | url := "https://news.163.com/" 13 | resp, err := http.Get(url) 14 | utils.HandleError(err, "http.Get") 15 | pageBytes, _ := io.ReadAll(resp.Body) 16 | defer resp.Body.Close() 17 | 18 | pattern := `\d*\s*]*>(.*?)\s*(\d*)` 19 | matched := utils.ExtractMatches(string(pageBytes), pattern) 20 | 21 | var obj []map[string]interface{} 22 | for index, item := range matched { 23 | hot, err := strconv.ParseFloat(item[3], 64) 24 | utils.HandleError(err, "strconv.ParseFloat") 25 | obj = append(obj, map[string]interface{}{ 26 | "index": index + 1, 27 | "title": item[2], 28 | "url": item[1], 29 | "hotValue": fmt.Sprintf("%.1f万", hot/10000), 30 | }) 31 | } 32 | api := map[string]interface{}{ 33 | "code": 200, 34 | "message": "网易新闻", 35 | "icon": "https://news.163.com/favicon.ico", // 16 x 16 36 | "obj": obj, 37 | } 38 | return api 39 | } 40 | -------------------------------------------------------------------------------- /app/weibo.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | ) 10 | 11 | type wbResponse struct { 12 | Item wbItem `json:"data"` 13 | } 14 | type wbItem struct { 15 | Data []wbData `json:"realtime"` 16 | } 17 | type wbData struct { 18 | Title string `json:"word"` 19 | HotValue float64 `json:"num"` 20 | } 21 | 22 | func WeiboHot() map[string]interface{} { 23 | url := "https://weibo.com/ajax/side/hotSearch" 24 | // 1.去网站拿数据 25 | resp, err := http.Get(url) 26 | utils.HandleError(err, "http.Get error") 27 | defer resp.Body.Close() 28 | // 2.读取页面内容 29 | pageBytes, err := io.ReadAll(resp.Body) 30 | utils.HandleError(err, "io.ReadAll error") 31 | var resultMap wbResponse 32 | err = json.Unmarshal(pageBytes, &resultMap) 33 | utils.HandleError(err, "json.Unmarshal error") 34 | 35 | realtimeList := resultMap.Item.Data 36 | 37 | obj := []map[string]interface{}{} 38 | for index, item := range realtimeList { 39 | obj = append(obj, map[string]interface{}{ 40 | "index": index + 1, 41 | "title": item.Title, 42 | "url": "https://s.weibo.com/weibo?q=" + item.Title, 43 | "hotValue": fmt.Sprintf("%.1f万", item.HotValue/10000), 44 | }) 45 | } 46 | api := map[string]interface{}{ 47 | "code": 200, 48 | "message": "微博", 49 | "icon": "https://www.weibo.com/favicon.ico", // 32 x 32 50 | "obj": obj, 51 | } 52 | return api 53 | } 54 | -------------------------------------------------------------------------------- /app/xinjingbao.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func Xinjingbao() map[string]interface{} { 10 | url := "https://www.bjnews.com.cn/" 11 | resp, err := http.Get(url) 12 | utils.HandleError(err, "http.Get") 13 | defer resp.Body.Close() 14 | pageBytes, err := io.ReadAll(resp.Body) 15 | utils.HandleError(err, "io.ReadAll") 16 | 17 | pattern := `

    \s*]*>\s*]*>\d*\s*(.*?)\s*

    [\s\S]*?(.*?)
    ` 18 | matched := utils.ExtractMatches(string(pageBytes), pattern) 19 | 20 | var obj []map[string]interface{} 21 | for index, item := range matched { 22 | obj = append(obj, map[string]interface{}{ 23 | "index": index + 1, 24 | "title": item[2], 25 | "url": item[1], 26 | "hotValue": item[3], 27 | }) 28 | } 29 | api := map[string]interface{}{ 30 | "code": 200, 31 | "message": "新京报", 32 | "icon": "https://www.bjnews.com.cn/favicon.ico", // 20 x 20 33 | "obj": obj, 34 | } 35 | return api 36 | } 37 | -------------------------------------------------------------------------------- /app/zhihu.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "api/utils" 5 | "encoding/json" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | type zhResponse struct { 11 | Response response `json:"recommend_queries"` 12 | } 13 | type response struct { 14 | Data []zhData `json:"queries"` 15 | } 16 | type zhData struct { 17 | Title string `json:"query"` 18 | } 19 | 20 | func Zhihu() map[string]interface{} { 21 | url := "https://www.zhihu.com/api/v4/search/recommend_query/v2" 22 | resp, err := http.Get(url) 23 | utils.HandleError(err, "http.Get") 24 | defer resp.Body.Close() 25 | pageBytes, err := io.ReadAll(resp.Body) 26 | utils.HandleError(err, "io.ReadAll") 27 | var resultMap zhResponse 28 | err = json.Unmarshal(pageBytes, &resultMap) 29 | utils.HandleError(err, "json.Unmarshal") 30 | 31 | data := resultMap.Response.Data 32 | 33 | var obj []map[string]interface{} 34 | for index, item := range data { 35 | obj = append(obj, map[string]interface{}{ 36 | "index": index + 1, 37 | "title": item.Title, 38 | "url": "https://www.zhihu.com/search?q=" + item.Title, 39 | }) 40 | } 41 | api := map[string]interface{}{ 42 | "code": 200, 43 | "message": "知乎", 44 | "icon": "https://static.zhihu.com/static/favicon.ico", // 32 x 32 45 | "obj": obj, 46 | } 47 | return api 48 | } 49 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module api 2 | 3 | go 1.23.4 4 | 5 | require ( 6 | github.com/bytedance/sonic v1.12.7 // indirect 7 | github.com/bytedance/sonic/loader v0.2.2 // indirect 8 | github.com/cloudwego/base64x v0.1.4 // indirect 9 | github.com/cloudwego/iasm v0.2.0 // indirect 10 | github.com/gabriel-vasile/mimetype v1.4.8 // indirect 11 | github.com/gin-contrib/sse v1.0.0 // indirect 12 | github.com/gin-gonic/gin v1.10.0 // indirect 13 | github.com/go-playground/locales v0.14.1 // indirect 14 | github.com/go-playground/universal-translator v0.18.1 // indirect 15 | github.com/go-playground/validator/v10 v10.23.0 // indirect 16 | github.com/goccy/go-json v0.10.4 // indirect 17 | github.com/json-iterator/go v1.1.12 // indirect 18 | github.com/klauspost/cpuid/v2 v2.2.9 // indirect 19 | github.com/leodido/go-urn v1.4.0 // indirect 20 | github.com/mattn/go-isatty v0.0.20 // indirect 21 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 22 | github.com/modern-go/reflect2 v1.0.2 // indirect 23 | github.com/pelletier/go-toml/v2 v2.2.3 // indirect 24 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 25 | github.com/ugorji/go/codec v1.2.12 // indirect 26 | golang.org/x/arch v0.13.0 // indirect 27 | golang.org/x/crypto v0.32.0 // indirect 28 | golang.org/x/net v0.34.0 // indirect 29 | golang.org/x/sys v0.29.0 // indirect 30 | golang.org/x/text v0.21.0 // indirect 31 | google.golang.org/protobuf v1.36.2 // indirect 32 | gopkg.in/yaml.v3 v3.0.1 // indirect 33 | ) 34 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q= 2 | github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I= 3 | github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= 4 | github.com/bytedance/sonic/loader v0.2.2 h1:jxAJuN9fOot/cyz5Q6dUuMJF5OqQ6+5GfA8FjjQ0R4o= 5 | github.com/bytedance/sonic/loader v0.2.2/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= 6 | github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= 7 | github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= 8 | github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= 9 | github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= 10 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= 13 | github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= 14 | github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= 15 | github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= 16 | github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= 17 | github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= 18 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 19 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 20 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 21 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 22 | github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= 23 | github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= 24 | github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= 25 | github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= 26 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 27 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 28 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 29 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 30 | github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= 31 | github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= 32 | github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 33 | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 34 | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 35 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 36 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 37 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 38 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 39 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 40 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 41 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 42 | github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= 43 | github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= 44 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 45 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 46 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 47 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 48 | github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 49 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 50 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 51 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 52 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 53 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 54 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 55 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 56 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 57 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 58 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 59 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 60 | golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA= 61 | golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= 62 | golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= 63 | golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= 64 | golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= 65 | golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= 66 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 67 | golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= 68 | golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 69 | golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= 70 | golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 71 | google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= 72 | google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 73 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 74 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 75 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 76 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 77 | nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= 78 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 79 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "api/all" 5 | "api/app" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func main() { 11 | r := gin.Default() 12 | 13 | // 定义路由映射 14 | routes := map[string]func() map[string]interface{}{ 15 | "/bilibili": app.Bilibili, 16 | "/360search": app.Search360, 17 | "/acfun": app.Acfun, 18 | "/csdn": app.CSDN, 19 | "/dongqiudi": app.Dongqiudi, 20 | "/douban": app.Douban, 21 | "/douyin": app.Douyin, 22 | "/github": app.Github, 23 | "/guojiadili": app.Guojiadili, 24 | "/history": app.History, 25 | "/hupu": app.Hupu, 26 | "/ithome": app.Ithome, 27 | "/lishipin": app.Lishipin, 28 | "/pengpai": app.Pengpai, 29 | "/qqnews": app.Qqnews, 30 | "/shaoshupai": app.Shaoshupai, 31 | "/sougou": app.Sougou, 32 | "/toutiao": app.Toutiao, 33 | "/v2ex": app.V2ex, 34 | "/wangyinews": app.WangyiNews, 35 | "/weibo": app.WeiboHot, 36 | "/xinjingbao": app.Xinjingbao, 37 | "/zhihu": app.Zhihu, 38 | "/kuake": app.Quark, 39 | "/souhu": app.Souhu, 40 | "/baidu": app.Baidu, 41 | "/renmin": app.Renminwang, 42 | "/nanfang": app.Nanfangzhoumo, 43 | "/360doc": app.Doc360, 44 | "/cctv": app.CCTV, 45 | "/all": all.All, 46 | } 47 | 48 | // 注册路由 49 | for path, handler := range routes { 50 | r.GET(path, func(c *gin.Context) { 51 | c.JSON(200, handler()) 52 | }) 53 | } 54 | 55 | r.Run(":1111") 56 | } 57 | -------------------------------------------------------------------------------- /utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | ) 7 | 8 | // 处理异常 9 | func HandleError(err error, why string) { 10 | if err != nil { 11 | fmt.Println(why, err) 12 | } 13 | } 14 | 15 | func ExtractMatches(text, pattern string) [][]string { 16 | regex := regexp.MustCompile(pattern) 17 | matches := regex.FindAllStringSubmatch(text, -1) 18 | return matches 19 | } 20 | --------------------------------------------------------------------------------