登录
首页 >  Golang >  Go问答

在Golang中使用Colly库将文本添加到映射中

来源:stackoverflow

时间:2024-02-13 22:36:22 248浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《在Golang中使用Colly库将文本添加到映射中》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

问题内容

我正在使用 colly 包制作一个网络抓取工具,它从网站收集 contestnamecontesttime 并制作一个 json 文件。

所以我确实喜欢这个

    contests := make(map[string]map[string]map[string]map[string]string)
    
    contests["atcoder"] = make(map[string]map[string]map[string]string)
    contests["atcoder"]["futurecontests"] = make(map[string]map[string]string)

    atcoderfunc(contests)


.................code..........

func atcoderfunc(contests map[string]map[string]map[string]map[string]string) {
    collector := colly.newcollector(
        colly.alloweddomains("atcoder.jp", "www.atcoder.jp"),
    )

    // loc, _ := time.loadlocation("asia/calcutta")
    // format := "2006-01-02 15:04:05"
    // var i int
    format := "2006-01-02 15:04:05-0700"
    loc, _ := time.loadlocation("asia/calcutta")


    for i := 1; i < 10; i++ {
        contestseltime := fmt.sprintf("#contest-table-upcoming  div  div  table  tbody  tr:nth-child(%d)  td:nth-child(1)  a", i+1)
        contestselname := fmt.sprintf("#contest-table-upcoming  div  div  table  tbody  tr:nth-child(%d)  td:nth-child(2)", i)

        // for contest name
        collector.onhtml(contestselname, func(element *colly.htmlelement) {
            contestname := element.childtext("a")
            fmt.printf("%t \n", contestname)
            fmt.println(contestname) // instead of printing i want to add it to the contests["atcoder"]["futurecontests"] map and print like json 
            

        })

        // for contesttime
        collector.onhtml(contestseltime, func(element *colly.htmlelement) {
            conteststarttime := element.childtext("time")
            parsed_time, _ := time.parse(format, conteststarttime)
            ist_time := parsed_time.in(loc)
            fmt.println("time in ist", ist_time) // instead of printing i want to add it to the contests["atcoder"]["futurecontests"] map.
        })

    }

    collector.onrequest(func(request *colly.request) {
        fmt.println("visiting", request.url.string())
    })

    collector.visit("https://atcoder.jp/contests")

}


有什么想法吗? 我尝试像这样将值添加到地图

contests["atcoder"]["futurecontests"] = map[string]string{
                "name": string(contestname),
            }

我想像这样制作json

{
  "AtCoder": {
    "FutureContests": {
      "1": {
        "Name": "Contest name",
        "Start": "time here"
      },
      "2": {
        "Name": "Contest name",
        "Start": "time here"
      }
    }
  }
}

但它给出错误 cannot use (map[string]string literal) (map[string]string 类型的值) 作为赋值 中的 map[string]map[string]string 值

有什么想法吗?


正确答案


错误发生在地图分配中。管理如此嵌套的结构非常困难,但我找到了一种成功处理它的方法。让我展示一下代码:

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
    "time"

    "github.com/gocolly/colly/v2"
)

type contest struct{}

func AtcoderFunc(contests map[string]map[string]map[string]string) {
    collector := colly.NewCollector(
        colly.AllowedDomains("atcoder.jp", "www.atcoder.jp"),
    )

    format := "2006-01-02 15:04:05-0700"
    loc, _ := time.LoadLocation("Asia/Calcutta")

    contests["UpcomingContest"] = make(map[string]map[string]string)

    for i := 1; i < 3; i++ {
        rawI := strconv.Itoa(i)
        contests["UpcomingContest"][rawI] = make(map[string]string)

        contestSelTime := fmt.Sprintf("#contest-table-upcoming  div  div  table  tbody  tr:nth-child(%d)  td:nth-child(1)  a", i+1)
        contestSelName := fmt.Sprintf("#contest-table-upcoming  div  div  table  tbody  tr:nth-child(%d)  td:nth-child(2)", i)

        // for contest name
        collector.OnHTML(contestSelName, func(element *colly.HTMLElement) {
            contestName := element.ChildText("a")
            contests["UpcomingContest"][rawI]["Name"] = contestName
        })

        // for contestTime
        collector.OnHTML(contestSelTime, func(element *colly.HTMLElement) {
            ContestStartTime := element.ChildText("time")
            parsed_time, _ := time.Parse(format, ContestStartTime)
            IST_time := parsed_time.In(loc)
            contests["UpcomingContest"][rawI]["Time"] = fmt.Sprint(IST_time)
        })
    }

    collector.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    collector.Visit("https://atcoder.jp/contests")
}

func main() {
    contests := make(map[string]map[string]map[string]map[string]string)
    contests["AtCoder"] = make(map[string]map[string]map[string]string)

    AtcoderFunc(contests["AtCoder"])

    data, _ := json.MarshalIndent(contests, "", "  ")
    fmt.Println(string(data))
}

我或多或少保留了你的结构。除了解决问题之外,我还通过更改一些名称并删除未使用的语句来重构了您的示例。最后,我使用 marshalindent 函数来美化打印到终端上的 json 字符串。
让我知道是否也适合您!

今天关于《在Golang中使用Colly库将文本添加到映射中》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>