就这?我花了一个小时找问题?记一次憨批行为长长记性
昨天接到一个派发下来的小任务,爬取某个URL中N个子类下N天的每天24小时的数据,最开始打算用PHP实现,想着也有段时间没写Go了,遂决定使用Go实现。思路非常简单,就是发起一个CURL请求,带上参数,将获取到json进行分组包装返回给算法部门,就是这样的一个简单的东西,花了我一个小时。
这个Api接收两个参数guid(筛选的类型别)
和pubtime(筛选的时间,时间粒度为h)
,缺一不可,并且需要设置Header
Postman的带参请求结果,HttpCode为200,数据也正常返回
先来看看十分钟梭出来的第一版
func main(){
stationList := [...] string { "xxx", "xxx"}
dateList := genDate(20, 24)
for _, stationCode := range stationList {
for _, date := range dateList {
url := "http://xxx.com/api/v1/air_all/station_realtime?pubtime=" + date + "&guid" + stationCode
GetUrl(url, date, stationCode)
}
}
}
// 四月-生成指定天数的指定小时时间
func genDate(dateNum int, hourNum int) []string {
var publishTimeList []string
startTime := time.Date(2020,03, 31, 24, 00, 00, 00, time.Local).Unix()
publishTimeList = append(publishTimeList, time.Unix(startTime, 0).Format("2006-01-02 15:04:05")) // 将初始日期append
var (
nextDate time.Time
thisDate time.Time
nextHour time.Time
thisHour time.Time
)
thisDate = time.Unix(startTime - 86400, 0)
for i := 1; i <= dateNum; i++ {
// 获取每一天
nextDate = time.Unix(thisDate.Unix() + 86400, 0) //增加一天
thisDate = nextDate
thisHour = time.Unix(thisDate.Unix(), 0) // 当前日
for j := 1; j <= hourNum; j++ {
nextHour = time.Unix(thisHour.Unix() + 3600, 0) //增加一小时
publishTimeList = append(publishTimeList, nextHour.Format("2006-01-02 15:04:05")) // 将初始日期append
thisHour = nextHour
}
}
return publishTimeList
}
func GetUrl(url string) {
client := &http.Client{}
req,_ := http.NewRequest(http.MethodGet, url,nil)
req.Header.Add("Authorization","xxxxx")
resp,_ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(req.URL.String(), resp, string(body))
}
代码很简单,应该很好懂,但是print返回的resp如下
😯❓❓❓❓
我可以理解你401,说明未授权也就是Header头的Authorization没有带上
于是我去尝试了这个URL对于参数问题的返回
不带时间的并且guid是错误的时候是441
不带分类的时候是450
不带时间,guid正确的话会返回正常结果(最新时间)
441,200,450,401都有了,400呢❓❓❓❓
因为我们都知道400是Bad Request,基本上也就是参数问题嘛,于是我在terminal中print出了拼接的URL,然后直接复制去Postman
没有问题,正常返回
当时就非常纳闷了,把参数一个个打出来看,又去检查发送REQUEST的方式是否正确(现在想来或许当时是钻牛角尖了没静下来想为啥会400),在开始这个小任务大约四十分钟(一半时间都在找400的问题)的时候,我决定写个接口来测试下看看到底是传递了什么东西过来(之前因为懒得写就把这个方案放在最后了).
接收请求的地方用的Node.Js,非常简单,分别打印出url、header、query
Go这边的Res显示请求成功,返回了200
Node这边,请求是过来了的
尝试带个参试试,对比url和获取到的query可以看到,没有问题
那我们结合实际请求来看看,Go部分显示400,Node部分没有任何输出
带上guid就能够获取到😓
这么看起来应该就是date出了问题,打印看起来是一个平平无奇的字符串
等等,空格❓❓❓❓
我尝试去掉空格,直接传入2020-04-01
😓😓😓😓
看来就是这个空格的问题了,我就尝试不直接拼接在URL,而改为使用query了
func GetUrl(url string, date string, stationCode string) {
client := &http.Client{}
req,_ := http.NewRequest(http.MethodGet, url,nil)
q := req.URL.Query()
q.Add("pubtime", date)
q.Add("guid", stationCode)
req.URL.RawQuery = q.Encode()
req.Header.Add("Authorization","xxxx")
resp,_ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(req.URL.String(), resp, string(body))
}
Node这边接收成功
调整为需要的地址以后即成功
总结:事后回想起来真的是憨批行为,为了偷懒直接去拼接url,忘记了去特殊字符转义,希望大家记住我的教训,不要浪费时间
本作品采用《CC 协议》,转载必须注明作者和本文链接
:joy:我也遇到过这个比较憨的问题
嗯 这事我也遇到过。哈哈 :joy:
记忆深刻
写PHP的时候,对方.net调我的接口犯过你这个错误,当时需要参数加密,也是因为空格被转换加密了,哈哈哈,你还好只用了一个小时,当时那家伙缠着我缠了一下午,除了空格,传参的时候还有null和空字符串的问题也比较常见。。。
你这也是爬取天气数据吗.