├── .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*<\/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 := `
(.*?)
` 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*(.*?)
` 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 := `\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 := `