剑桥词典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
写我们的刮擦逻辑
-
初始化:
- 代码开始初始化两个重要变量:
c
(collector)和parsingResult
。 -
c
是一个名为Colly的Web刮擦工具的实例,该工具用于从网页中导航和提取数据。 -
parsingResult
是一种结构,可以保留网络刮擦的结果。
- 代码开始初始化两个重要变量:
-
初始化功能(
init
):- 在
init
函数中,设置了colly collectorc
。 - 它被配置为仅访问域“ dictionary.cambridge.org”。
-
AllowURLRevisit
设置为true,这意味着收集者可以在需要时重新访问相同的URL。 - 称为
settingSearch
函数,该功能设置了数据提取规则。
- 在
-
设置数据提取规则(
settingSearch
函数):- 此功能定义了从剑桥词典网页中提取特定数据的规则。
- 它使用Colly的
OnHTML
方法来指定页面上某些HTML元素时该做什么。 - 例如,当找到具有“ pos-header”类的HTML元素时,它提取发音(kk)和语音的一部分(pos)。
- 当找到具有“ def-block”类的HTML元素时,它提取含义和示例句子。
-
搜索功能(
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格式化我们的刮擦结果
此数据结构和功能用于组织和格式化有关单词及其含义的信息。它们有助于使数据更加人性化,适合于演示文稿,例如在用户界面或聊天机器人响应中。
-
数据结构:
-
meaningAndSentence
:此结构代表单词的含义和相关的示例句子。它包含两个字段:-
Meaning
:一个存储单词含义的字符串。 -
Sentence
:一个存储与单词含义相关的示例句子的字符串列表。
-
-
-
wordMeaning
:此结构表示有关单词的信息,包括其发音,语音的一部分以及含义和句子的列表。它包含以下字段:-
WordToSearch
:一个存储正在搜索的单词的字符串。 -
KK
:一个存储单词发音的字符串。 -
POS
:一个存储单词演讲部分的字符串。 -
ResultList
:meaningAndSentence
结构的列表,代表与单词相关的不同含义和句子。
-
-
formatCrawlerResult
功能:- 此功能将字符串(
result
)作为输入,然后对其进行处理以删除不必要的空间和字符。 - 它使用正则表达式从输入字符串中删除额外的空间,结肠和其他不需要的字符。
- 然后返回处理后的字符串。
- 此功能将字符串(
-
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
如果您想了解更多有关它的信息,以及如何将此API集成到我的电报频道或Discord或任何其他平台(例如Slack等)中,那么您可以在我的GitHub Repo
上找到代码