【问题标题】:Why can't Golang download certain webpages?为什么 Golang 不能下载某些网页?
【发布时间】:2018-07-31 18:31:32
【问题描述】:

我想下载 Fantasy Football Data 以在 Go 中进行分析,但是当我尝试从 this api page 下载时,我得到一个空响应,即使该代码适用于其他网站,例如this api page

最小复制,输出一个空数组。

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

const AllPlayerData = "https://fantasy.premierleague.com/drf/bootstrap-static"

func main() {
    downloadAllData()
}

func downloadAllData() {
    client := &http.Client{
        Timeout: 20 * time.Second,
    }

    response, err := client.Get(AllPlayerData)
    if err != nil {
        fmt.Println("Unable to download player data.")
        return
    }

    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Println("Failed to read response")
        return
    }

    defer response.Body.Close()

    fmt.Println(body)
}

同样的网页在 Python 中可以正常下载:

import requests
url = "https://fantasy.premierleague.com/drf/bootstrap-static"
r = requests.get(url)
print(r.content)

我认为这与例如Ajax calls 在 Chrome 中查看网络请求不会显示任何超出页面加载本身的内容

【问题讨论】:

  • 您是否尝试记录错误消息? fmt.Println("error: %v", err) 如果没有错误,只是一个空响应,你检查响应头了吗?也许这是python自动遵循的重定向,但Go客户端没有。
  • 没有任何错误消息,也没有任何有用的响应标头。响应的状态为 200,但内容长度为 0

标签: go webpage go-http


【解决方案1】:

他们正在对用户代理进行某种验证,以下代码有效:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

const AllPlayerData = "https://fantasy.premierleague.com/drf/bootstrap-static"

func main() {
    downloadAllData()
}

func downloadAllData() {
    client := &http.Client{
        Timeout: 20 * time.Second,
    }

    request, err := http.NewRequest(http.MethodGet, AllPlayerData, nil)
    if err != nil {
        fmt.Println("Unable to create request.")
        return
    }
    request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36")
    response, err := client.Do(request)
    if err != nil {
        fmt.Println("Unable to download player data.")
        return
    }

    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Println("Failed to read response")
        return
    }

    defer response.Body.Close()

    fmt.Println(string(body))
}

【讨论】:

  • 已经解决了,非常感谢戴夫!我假设 python 默认应用标题,但你知道 Postman 是否也是如此?
  • Go 实际上默认也有一个用户代理,const defaultUserAgent = "Go-http-client/1.1",我想 PostMan 要么有一个,要么使用你的浏览器。很难知道为什么 Go 的默认设置被阻止了,但这只是抓取的常见问题 - 通常您希望尽可能模拟真实的浏览器
  • 这是有道理的。非常感谢:)
  • 看起来他们正在检查Mozilla。我发送了一个 only Mozilla 作为用户代理的请求,他们发送了数据。
猜你喜欢
  • 1970-01-01
  • 2012-06-22
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2012-04-12
  • 2014-08-27
相关资源
最近更新 更多