Go-Colly中如何在POST请求中正确传递Slice类型参数?
问题:Go-Colly传递多值POST参数(dwz[]数组)失败
需要调用http://www.isewase.de/dwz/的计算功能,该网站的POST请求需携带多个dwz[]参数,请求示例如下:
表单格式:
dwz_name: 1000-100 geb: 1990 punkte: 1 dwz[]: 1300 dwz[]: 1400 dwz[]: ... Los: DWZ berechnen! name: kennwort:URL编码格式:
dwz_name=1000-100&geb=1990&punkte=1&dwz%5B%5D=1300&dwz%5B%5D=1400&dwz%5B%5D=&...&Los=DWZ+berechnen%21&name=&kennwort=
用户编写的Go-Colly代码仅让服务器识别了第一个dwz值,返回结果与仅传入1300时一致,核心问题是colly.Post的map[string]string参数无法直接传递多值数组。
解决方案
Colly的Post方法使用map传参时,同一key仅会保留最后一个值。要传递多值参数,需通过以下两种方式实现:
方法1:使用PostRaw发送预编码表单数据
手动构建符合要求的URL编码字符串,再通过PostRaw发送请求:
package main import ( "fmt" "net/url" "github.com/gocolly/colly" ) func main() { dwz := []string{"1300", "1400"} // 构建表单数据集合 formData := url.Values{} formData.Set("dwz_name", "1000-100") formData.Set("geb", "1900") formData.Set("punkte", "1") formData.Set("Los", "DWZ berechnen!") formData.Set("name", "") formData.Set("kennwort", "") // 逐个添加dwz[]参数 for _, val := range dwz { formData.Add("dwz[]", val) } c := colly.NewCollector() c.OnHTML("body > form > fieldset:nth-child(4) > dl > dd:nth-child(8)", func(h *colly.HTMLElement) { fmt.Println(h.Text) }) // 发送编码后的表单数据,自动设置正确的Content-Type c.PostRaw("http://www.isewase.de/dwz/", []byte(formData.Encode())) }
方法2:通过Request对象手动构建请求
直接创建HTTP请求并设置表单数据,再由Colly发送:
package main import ( "fmt" "net/http" "net/url" "strings" "github.com/gocolly/colly" ) func main() { dwz := []string{"1300", "1400"} formData := url.Values{} formData.Set("dwz_name", "1000-100") formData.Set("geb", "1900") formData.Set("punkte", "1") formData.Set("Los", "DWZ berechnen!") formData.Set("name", "") formData.Set("kennwort", "") for _, val := range dwz { formData.Add("dwz[]", val) } c := colly.NewCollector() c.OnHTML("body > form > fieldset:nth-child(4) > dl > dd:nth-child(8)", func(h *colly.HTMLElement) { fmt.Println(h.Text) }) // 创建POST请求 req, err := http.NewRequest("POST", "http://www.isewase.de/dwz/", strings.NewReader(formData.Encode())) if err != nil { fmt.Println("请求创建失败:", err) return } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // 用Colly执行请求 c.Do(req) }
原代码失败原因
原代码通过strings.Join将多个dwz值拼接为单个字符串,传给dwz[]键,服务器会将该字符串视为单个dwz[]参数的值,而非多个独立参数,因此仅识别了第一个数值。
内容的提问来源于stack exchange,提问作者nicksheen
相关产品推荐
相关产品推荐

