我有一个如下代码来从 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)
})
})
}
解决方案:
您可以在下面看到答案,如果您愿意,可以查看 看看为什么使用这种解决方案
顺便说一句,我们可以使用迭代从映射中获取特定值。我也有一个代码。但如果您有任何更简单的方法,请发表评论
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
}
最佳答案
您可以通过http Post请求获取。不要忘记在请求中添加 X-Requested-With header 。
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
}
关于api - Golang 表网络抓取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72649649/