如何在Go中构建剑桥词典API
#编程 #教程 #api #go

剑桥词典API

让我们通过基于Word Search
爬行数据来构建功能齐全的剑桥字典API
我们将使用colly抓取结果数据和正则拨号,以格式化结果,并使用JSON编号编码和编码数据。

在您的计算机中创建一个文件夹词典 - api并创建一个main.go文件并运行go mod init dictionary-api,然后在terminal

中添加新的依赖项运行go mod tidy时,然后运行go mod tidy

步骤-1安装依赖项

我们将安装Colly一个出色的Web刮擦框架

go get github.com/gocolly/colly

写我们的刮擦逻辑

  1. 初始化:

    • 代码开始初始化两个重要变量:c(collector)和parsingResult
    • c是一个名为Colly的Web刮擦工具的实例,该工具用于从网页中导航和提取数据。
    • parsingResult是一种结构,可以保留网络刮擦的结果。
  2. 初始化功能(init):

    • init函数中,设置了colly collector c
    • 它被配置为仅访问域“ dictionary.cambridge.org”。
    • AllowURLRevisit设置为true,这意味着收集者可以在需要时重新访问相同的URL。
    • 称为settingSearch函数,该功能设置了数据提取规则。
  3. 设置数据提取规则(settingSearch函数):

    • 此功能定义了从剑桥词典网页中提取特定数据的规则。
    • 它使用Colly的OnHTML方法来指定页面上某些HTML元素时该做什么。
    • 例如,当找到具有“ pos-header”类的HTML元素时,它提取发音(kk)和语音的一部分(pos)。
    • 当找到具有“ def-block”类的HTML元素时,它提取含义和示例句子。
  4. 搜索功能(Search函数):

    • Search功能用于在剑桥词典网站上执行单词搜索。
    • 它采用wordToSearch参数,这是您要查找的单词。
    • 它在开始新搜索之前将parsingResult重置为空。
    • 它使用Colly访问指定单词的剑桥词典页面。
    • 刮擦页面后,它返回了parsingResult,现在包含单词的发音,语音的一部分,含义和示例句子。
package main

import (
    "github.com/gocolly/colly"
)

var (
    c             *colly.Collector
    parsingResult wordMeaning
)

func init() {
    c = colly.NewCollector(
        colly.AllowedDomains("dictionary.cambridge.org"),
    )
    c.AllowURLRevisit = true
    settingSearch()
}

func settingSearch() {
    c.OnHTML(".pos-header.dpos-h", func(e *colly.HTMLElement) {
        // KK
        e.ForEach(".us.dpron-i .pron.dpron", func(i int, m *colly.HTMLElement) {
            parsingResult.KK = m.Text
        })
        // part of speech
        e.ForEach(".posgram.dpos-g.hdib.lmr-5", func(i int, m *colly.HTMLElement) {
            parsingResult.POS = m.Text
        })
    })
    // On every a element which has href attribute call callback
    c.OnHTML(".def-block.ddef_block", func(e *colly.HTMLElement) {
        var newMeaningAndSentence meaningAndSentence
        // meaning
        e.ForEach(".def.ddef_d.db", func(i int, m *colly.HTMLElement) {
            newMeaningAndSentence.Meaning = formatCrawlerResult(m.Text)
        })
        // sentence
        e.ForEach(".def-body.ddef_b .examp.dexamp", func(i int, m *colly.HTMLElement) {
            newMeaningAndSentence.Sentence = append(newMeaningAndSentence.Sentence, formatCrawlerResult(m.Text))
        })
        parsingResult.ResultList = append(parsingResult.ResultList, newMeaningAndSentence)
    })
}

func Search(wordToSearch string) wordMeaning {
    parsingResult = wordMeaning{}
    parsingResult.WordToSearch = wordToSearch
    err := c.Visit("https://dictionary.cambridge.org/dictionary/english/" + wordToSearch)
    if err != nil {
        panic(err)
    }
    return parsingResult
}

步骤-2使用Regex格式化我们的刮擦结果

此数据结构和功能用于组织和格式化有关单词及其含义的信息。它们有助于使数据更加人性化,适合于演示文稿,例如在用户界面或聊天机器人响应中。

  1. 数据结构
    • meaningAndSentence:此结构代表单词的含义和相关的示例句子。它包含两个字段:
      • Meaning:一个存储单词含义的字符串。
      • Sentence:一个存储与单词含义相关的示例句子的字符串列表。
  • wordMeaning:此结构表示有关单词的信息,包括其发音,语音的一部分以及含义和句子的列表。它包含以下字段:
    • WordToSearch:一个存储正在搜索的单词的字符串。
    • KK:一个存储单词发音的字符串。
    • POS:一个存储单词演讲部分的字符串。
    • ResultListmeaningAndSentence结构的列表,代表与单词相关的不同含义和句子。
  1. formatCrawlerResult功能

    • 此功能将字符串(result)作为输入,然后对其进行处理以删除不必要的空间和字符。
    • 它使用正则表达式从输入字符串中删除额外的空间,结肠和其他不需要的字符。
    • 然后返回处理后的字符串。
  2. PreprocessingJSONToString函数

    • 此功能将wordMeaning结构(preOutput)作为输入,并准备一个格式的字符串以显示。
    • 它通过组合各种信息,包括单词,语音,发音,含义和示例句子来构造字符串。
    • 它将显示的含义数量限制为最多5(按maxMeaningLine指定)。
    • 返回格式的字符串,可用于以更可读的格式显示单词信息。
package main

import (
    "fmt"
    "regexp"
    "strings"
)

var maxMeaningLine int = 5

type meaningAndSentence struct {
    Meaning  string   `json:"meaning"`
    Sentence []string `json:"sentence"`
}

type wordMeaning struct {
    WordToSearch string               `json:"word"`
    KK           string               `json:"kk"`
    POS          string               `json:"pos"`
    ResultList   []meaningAndSentence `json:"result"`
}

func formatCrawlerResult(result string) string {
    space := regexp.MustCompile(`\s+`)
    removeSpace := space.ReplaceAllString(result, " ")
    // remove case of [ C ] or [ T ]
    corT := regexp.MustCompile(`\[\s+.\s+\]|:`)
    removeCorT := corT.ReplaceAllString(removeSpace, "")
    // remove leading space
    noSpaceDuplicate := strings.TrimSpace(removeCorT)
    // replace the needed escape character
    // escape := regexp.MustCompile(`\.|\'|\*|\[|\]|\(|\)|\~|\>|\#|\+|\-|\=|\||\{|\}|\.|\!`)
    // removeEscape := escape.ReplaceAllString(noSpaceDuplicate, `\$0`)

    s := noSpaceDuplicate
    return s
}

func PreprocessingJSONToString(preOutput wordMeaning) string {
    output := ""
    // title
    output += fmt.Sprintf(`*%s*  (_%s_)`, preOutput.WordToSearch, preOutput.POS) + "\n"
    output += preOutput.KK + "\n"

    for i, result := range preOutput.ResultList {
        if i+1 > maxMeaningLine {
            break
        }
        output += fmt.Sprintf("%d", i+1) + ". *" + result.Meaning + "*\n"
        if len(result.Sentence) > 0 {
            output += `\* _` + result.Sentence[0] + "_\n"
        }
    }

    return output
}

步骤-3编写带有端点的HTTP处理程序

SearchQueryHandler函数处理http请求,其中包含一个在URL路径中搜索的单词(例如,“/search/word”)。它提取单词,检索其含义,并以含义信息发送JSON响应。如果此过程中存在错误,则可能会惊慌并终止程序。

func SearchQueryHandler() {
    http.HandleFunc("/search/", func(w http.ResponseWriter, r *http.Request) {
        wordToSearch := strings.TrimPrefix(r.URL.Path, "/search/")
        outputJSON := getMeaning(wordToSearch)
        w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusOK)
        encodeError := json.NewEncoder(w).Encode(outputJSON)
        if encodeError != nil {
            panic(encodeError)
        }
    })
}

听和服务


func main() {
    SearchQueryHandler()
    // Start the HTTP server
    // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }

}

跑步

// it will find all the global functions and run it. It is because it did not step up go env GOPATH
// So for you - you can try  go run main.go
go run .
// OR
go run main.go

演示

我正在使用thunderclient扩展名vscode

Image Demo

如果您想了解更多有关它的信息,以及如何将此API集成到我的电报频道或Discord或任何其他平台(例如Slack等)中,那么您可以在我的GitHub Repo

上找到代码

Github Code