为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 表网络抓取

Golang 表网络抓取

Go
墨色风雨 2022-12-19 21:44:54
我有如下代码从 html 表中抓取特定的单元格值。您可以访问https://www.haremaltin.com/altin-fiyatlari网站并在检查模式下搜索“satis__ATA_ESKI”以查看该值。我是 golang 的初学者并且尽我最大的努力但不幸的是我无法获得那个价值。有人可以帮助我吗?顺便说一句,他们没有社区 api。还有一件事,添加 time.sleep 以等待页面加载。如果它返回“-”,那是因为页面还没有加载package mainimport ("fmt""log""net/http""github.com/PuerkitoBio/goquery")func main() {   url := "https://www.haremaltin.com/altin-fiyatlari"   resp, err := http.Get(url)   if err != nil {       log.Fatal(err)   }   defer resp.Body.Close()   if resp.StatusCode != 200 {       log.Fatalf("failed to fetch data: %d %s", resp.StatusCode, resp.Status)   }   doc, err := goquery.NewDocumentFromReader(resp.Body)   if err != nil {      log.Fatal(err)   }   doc.Find("tr__ATA_ESKI tr").Each(func(j int, tr *goquery.Selection) {      data := []string{}      tr.Find("td").Each(func(ix int, td *goquery.Selection) {           e := td.Text()           data = append(data, e)           fmt.Println(data)      })   })}
查看完整描述

3 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

您可以在下面看到答案,如果您愿意,可以

//img1.sycdn.imooc.com//63a06b020001cb9313130483.jpg

查看为什么使用这种解决方案


顺便说一句,我们可以使用迭代从地图中获取特定值。我也有一个代码。但是,如果您有任何更简单的方法,请发表评论


for _, v := range data { // we need value part of the map

    m, ok := v.(map[string]interface{}) // we need the convert the map 

                                    // into interface for iteration

    if !ok {

        fmt.Printf("Error %T", v)

    }

    for k, l := range m {

        if k == "ATA_ESKI"{ // the value we want is inside of this map

            a, ok := l.(map[string]interface{}) // interface convert again

            if !ok {

                fmt.Printf("Error %T", v)

            }

            for b,c := range a{

                if b == "satis"{ // the value we want

                    fmt.Println("Price is", c)

                }

            }

        }

    }

}

具有以下迭代的完整解决方案:


package main


import (

    "encoding/json"

    "fmt"

    "io/ioutil"

    "net/http"

    "strings"

)


func main() {

    fecthData()

}


func fecthData() (map[string]interface{}, error) {

    body := strings.NewReader("dil_kodu=tr")

    req, err := http.NewRequest("POST", 

"https://www.haremaltin.com/dashboard/ajax/doviz", body)

    if err != nil {

        // handle err

        return nil, err

    }

    req.Header.Set("X-Requested-With", "XMLHttpRequest")


    resp, err := http.DefaultClient.Do(req)

    if err != nil {

        // handle err

        return nil, err

    }

    defer resp.Body.Close()

    jsonData, err := ioutil.ReadAll(resp.Body)

    if err != nil {

        panic(err)

        return nil, err

    }


    var data map[string]interface{}

    err = json.Unmarshal(jsonData, &data)

    if err != nil {

        return nil, err

    }


    for _, v := range data {

        m, ok := v.(map[string]interface{})

        if !ok {

            fmt.Printf("Error %T", v)

        }

        for k, l := range m {

            if k == "ATA_ESKI" {

                a, ok := l.(map[string]interface{})

                if !ok {

                    fmt.Printf("Error %T", v)

                }

                for b, c := range a {

                    if b == "satis" {

                        fmt.Println("Price", c)

                    }

                }

            }

        }

    }


    return data, nil

}


查看完整回答
反对 回复 2022-12-19
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

您可以通过 http Post 请求获取。不要忘记将 X-Requested-With 标头添加到请求中。


func fecthData() (map[string]interface{}, error) {

    body := strings.NewReader("dil_kodu=tr")

    req, err := http.NewRequest("POST", "https://www.haremaltin.com/dashboard/ajax/doviz", body)

    if err != nil {

        // handle err

        return nil, err

    }

    req.Header.Set("X-Requested-With", "XMLHttpRequest")


    resp, err := http.DefaultClient.Do(req)

    if err != nil {

        // handle err

        return nil, err

    }

    defer resp.Body.Close()

    jsonData, err := ioutil.ReadAll(resp.Body)

    if err != nil {

        panic(err)

        return nil, err

    }

    var data map[string]interface{}

    err = json.Unmarshal(jsonData, &data)

    if err != nil {

        return nil, err

    }

    return data, nil

}


查看完整回答
反对 回复 2022-12-19
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

由于该表由 javascript 提供支持,我建议您使用不同的方法。这就是为什么。

你真正抓取的是

curl https://www.haremaltin.com/altin-fiyatlari > out.html

这个网页。您可以在终端中运行此 curl 并获得与 go 的 rest 请求完全相同的回复(精确是一个强词,大多数时候,肯定是这种情况)

如您所见,out.html您创建的文件中没有任何值,这就是您的 go 脚本未返回任何值的原因。

你需要运行 javascript 来填充页面,这样你就可以抓取它了。

我在几个项目中使用了这个https://github.com/chromedp/chromedp并取得了巨大的成功。通过使用此工具,您的工作流程将类似于……

  1. 打开无头浏览器

  2. 去网址

  3. 转储页面 html

  4. 用 goquery 解析

  5. 打印您的回复


查看完整回答
反对 回复 2022-12-19
  • 3 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信