You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.0 KiB
87 lines
2.0 KiB
package bingsearch
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
// newSys 创建 Bing 搜索系统对象
|
|
// 参数:
|
|
// - options: 系统选项
|
|
//
|
|
// 返回值:
|
|
// - sys: 系统对象指针
|
|
// - err: 创建过程中的错误
|
|
//
|
|
// 异常:
|
|
// - 无(最小实现,仅进行结构体初始化)
|
|
func newSys(options Options) (sys *BingSearch, err error) {
|
|
sys = &BingSearch{
|
|
options: options,
|
|
httpClient: &http.Client{Timeout: 30 * time.Second},
|
|
}
|
|
return
|
|
}
|
|
|
|
type BingSearch struct {
|
|
options Options
|
|
httpClient *http.Client
|
|
}
|
|
|
|
// Search 执行网页搜索(最小实现)
|
|
// 参数:
|
|
// - ctx: 上下文
|
|
// - query: 搜索关键词
|
|
// - count: 返回条数
|
|
// - offset: 偏移量
|
|
//
|
|
// 返回值:
|
|
// - results: BingResponse 最小结构
|
|
// - err: 调用过程中的错误
|
|
//
|
|
// 异常:
|
|
// - 当 API Key 未配置时返回错误
|
|
// - 当网络请求失败、HTTP 状态非 200 或解析 JSON 失败时返回错误
|
|
func (this *BingSearch) Search(ctx context.Context, query string, count, offset int) (results *BingResponse, err error) {
|
|
if this.options.ApiKey == "" {
|
|
err = fmt.Errorf("bing api key is empty")
|
|
return
|
|
}
|
|
endpoint := "https://api.bing.microsoft.com/v7.0/search"
|
|
values := url.Values{}
|
|
values.Set("q", query)
|
|
if count > 0 {
|
|
values.Set("count", fmt.Sprintf("%d", count))
|
|
}
|
|
if offset > 0 {
|
|
values.Set("offset", fmt.Sprintf("%d", offset))
|
|
}
|
|
mkt := this.options.Market
|
|
if mkt == "" {
|
|
mkt = "zh-CN"
|
|
}
|
|
values.Set("mkt", mkt)
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s?%s", endpoint, values.Encode()), nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
req.Header.Set("Ocp-Apim-Subscription-Key", this.options.ApiKey)
|
|
resp, err := this.httpClient.Do(req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
err = fmt.Errorf("bing http status %d", resp.StatusCode)
|
|
return
|
|
}
|
|
results = &BingResponse{}
|
|
if err = json.NewDecoder(resp.Body).Decode(results); err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|