猿问

Golang 表网络抓取

我有如下代码从 html 表中抓取特定的单元格值。您可以访问https://www.haremaltin.com/altin-fiyatlari网站并在检查模式下搜索“satis__ATA_ESKI”以查看该值。我是 golang 的初学者并且尽我最大的努力但不幸的是我无法获得那个价值。有人可以帮助我吗?顺便说一句,他们没有社区 api。还有一件事,添加 time.sleep 以等待页面加载。如果它返回“-”,那是因为页面还没有加载

package main


import (

"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)

      })

   })

}


墨色风雨
浏览 147回答 3
3回答

繁星点点滴滴

您可以在下面看到答案,如果您愿意,可以查看为什么使用这种解决方案顺便说一句,我们可以使用迭代从地图中获取特定值。我也有一个代码。但是,如果您有任何更简单的方法,请发表评论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 mainimport (    "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}

一只甜甜圈

您可以通过 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}

神不在的星期二

由于该表由 javascript 提供支持,我建议您使用不同的方法。这就是为什么。你真正抓取的是curl https://www.haremaltin.com/altin-fiyatlari > out.html这个网页。您可以在终端中运行此 curl 并获得与 go 的 rest 请求完全相同的回复(精确是一个强词,大多数时候,肯定是这种情况)如您所见,out.html您创建的文件中没有任何值,这就是您的 go 脚本未返回任何值的原因。你需要运行 javascript 来填充页面,这样你就可以抓取它了。我在几个项目中使用了这个https://github.com/chromedp/chromedp并取得了巨大的成功。通过使用此工具,您的工作流程将类似于……打开无头浏览器去网址转储页面 html用 goquery 解析打印您的回复
随时随地看视频慕课网APP

相关分类

Go
我要回答