BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / golang / #842同步于 2017/8/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖

【求助】Go爬虫无法获取论坛cookie的疑惑

buptlaogong
2017/8/7镜像同步8 回复
#### 背景 这两天尝试写个Go爬虫爬论坛,期望能登录后保存cookie,后续的访问都带着这个cookie。查看资料推荐用`net/http/cookiejar`。 目前能登录成功,获取成功登录Json。但是发现并未获取登录后的cookie,导致后续直接Get帖子正文报错**“您未登录,请登录后继续操作”** 请教各位大神,这种情况哪里出错了? #### 实现 ``` package main import ( "net/http/cookiejar" "net/url" "strings" "fmt" "net/http" "crypto/tls" "io/ioutil" ) func main() { // init cookiejar var cookieJar *cookiejar.Jar cookieJar, _ = cookiejar.New(nil) // init client with cookiejar httpClient := &http.Client{ Jar: cookieJar, } // login param postValues := url.Values{} postValues.Set("id", "ID") postValues.Set("passwd", "PWD") postValues.Set("s-mode", "0") postValues.Set("CookieDate", "3") // request for login httpReq, _ := http.NewRequest("POST", "https://bbs.byr.cn/user/ajax_login.json", strings.NewReader(postValues.Encode())) httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") httpReq.Header.Add("X-Requested-With", "XMLHttpRequest") httpReq.Header.Add("Connection", "keep-alive") httpReq.Header.Add("User-Agent", "Mozilla/5.0") httpReq.Header.Add("Referer", "https://bbs.byr.cn") httpReq.Header.Add("Accept", "application/json, text/javascript, */*; q=0.01") httpReq.Header.Add("authority", "bbs.byr.cn") // for nginx/1.10 httpClient.Transport = &http.Transport{ TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), } // login httpResp, _ := httpClient.Do(httpReq) fmt.Printf("req cookies: %s \n", httpReq.Cookies()) fmt.Printf("resp cookies: %s \n", httpResp.Cookies()) // request to get article content httpReq1, _ := http.NewRequest("GET", "https://bbs.byr.cn/article/Python/2034", nil) httpReq1.Header.Add("X-Requested-With", "XMLHttpRequest") httpResp1, _ := httpClient.Do(httpReq1) body, _ := ioutil.ReadAll(httpResp1.Body) fmt.Println(string(body)) } ``` 输出(可见cookie为空): ``` req cookies: [] resp cookies: [] (...省略...) <h5>产生错误的可能原因:</h5><ul><li><samp class="ico-pos-dot"></samp>您未登录,请登录后继续操作</li> (...省略...) ``` **困扰多时,求各位指点**
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
nullne机器人#1 · 2017/8/8
建议先使用抓包工具(推荐firefox下的tamper data配合firebug)抓包看一下, 然后确定请求时候的参数,以及预计的返回就可以写代码了 至于如何设置跟获取cookie, 这个很容易搜到: https://astaxie.gitbooks.io/build-web-application-with-golang/en/06.1.html
buptlaogong机器人#2 · 2017/8/8
感谢回复! 我发帖之前看了些python版的爬虫问题帖,也进行抓包看了cookie内容,同时也查了很多Go http资料。资料大多推荐直接用cookiejar,https://golang.org/pkg/net/http/#CookieJar 但是,我的困惑在于【我的代码为什么无法获取登录后的cookie(如输出内容,cookie为空),这段代码哪里错在哪里】,大神能否用自己的论坛账号运行下这段代码,看看能否打印出cookie?万分感谢 【 在 nullne 的大作中提到: 】 : 建议先使用抓包工具(推荐firefox下的tamper data配合firebug)抓包看一下, 然后确定请求时候的参数,以及预计的返回就可以写代码了 : 至于如何设置跟获取cookie, 这个很容易搜到: https://astaxie.gitbooks.io/build-web-application-with-golang/en/06.1.html : : ...................
lucashood机器人#3 · 2017/8/8
不知道能不能在登录后弄一个session 我不会go 我瞎说的,python的requests模块有session api 逃
buptlaogong机器人#4 · 2017/8/8
理论上不需要用session,看网上的示例,用cookieJar就能搞定,不知道为什么北邮人论坛的cookie无法获取 【 在 lucashood 的大作中提到: 】 : 不知道能不能在登录后弄一个session : 我不会go : 我瞎说的,python的requests模块有session api : ...................
nullne机器人#5 · 2017/8/9
@buptlaogong 的确是个问题 我今天测试了一下 应该是Go自己的实现问题吧 或者说论坛的Cookie不规范 我待会儿再测试一下 先贴一点代码过来 所以简单的办法 就是你自己从header 里面解析 然后自己拼接cookie package main import ( "fmt" "log" "net/http" "net/http/cookiejar" "net/http/httptest" "net/url" "time" "golang.org/x/net/publicsuffix" ) func main() { // Start a server to give us cookies. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if cookie, err := r.Cookie("Flavor"); err != nil { // Illegal cookie name http.SetCookie(w, &http.Cookie{Name: "map[Flavor]", Value: "Chocolate Chip"}) // Cannot process Expires and Value http.SetCookie(w, &http.Cookie{Name: "map[Flavor]", Value: "Chocolate Chip", Path: "/", Expires: time.Now()}) // normal cookie http.SetCookie(w, &http.Cookie{Name: "only", Value: "cookie"}) } else { cookie.Value = "Oatmeal Raisin" http.SetCookie(w, cookie) } })) defer ts.Close() u, err := url.Parse(ts.URL) if err != nil { log.Fatal(err) } // All users of cookiejar should import "golang.org/x/net/publicsuffix" jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) if err != nil { log.Fatal(err) } client := &http.Client{ Jar: jar, } resp, err := client.Get(u.String()) if err != nil { log.Fatal(err) } // all cookies above will show in header "Set-Cookie" fmt.Printf("header in request: %+v\n", resp.Header) // only normal cookie will show here fmt.Printf("cookies in request: %+v\n", resp.Cookies()) // only normal cookie will show here fmt.Printf("cookies in jar: %+v\n", jar.Cookies(u)) }
mushroomboy机器人#6 · 2017/8/9
我在v2见过你,哈哈
buptlaogong机器人#7 · 2017/8/29
【 在 nullne 的大作中提到: 】 : @buptlaogong 的确是个问题 我今天测试了一下 应该是Go自己的实现问题吧 或者说论坛的Cookie不规范 我待会儿再测试一下 先贴一点代码过来 : 所以简单的办法 就是你自己从header 里面解析 然后自己拼接cookie : [code=c] : ................... 貌似go解析Set-Cookie时认为 [ 是无效的字符,所以httpResp.Cookies()返回空,下面是把httpResp整个打印出来获取的Set-Cookie header: ```JSON "Set-Cookie":[]string{ "nforum[UTMPUSERID]=guest; path=/; domain=bbs.byr.cn", "nforum[UTMPKEY]=21970208; path=/; domain=bbs.byr.cn", "nforum[UTMPNUM]=29282; path=/; domain=bbs.byr.cn", "nforum[UTMPUSERID]=guest; path=/; domain=bbs.byr.cn", "nforum[UTMPKEY]=21970208; path=/; domain=bbs.byr.cn", "nforum[UTMPNUM]=29282; path=/; domain=bbs.byr.cn"} ``` 下面是go解析cookie时依照的RFC标准: [http://tools.ietf.org/html/rfc6265](http://tools.ietf.org/html/rfc6265) ``` cookie-pair = cookie-name "=" cookie-value cookie-name = token cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E ; US-ASCII characters excluding CTLs, ; whitespace DQUOTE, comma, semicolon, ; and backslash token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT ``` 标准里有如下规范: ``` token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT ``` 也就是说,token不能包含分隔符,但是`"[" "]"`又恰好属于分隔符,所以被判为无效
buptlaogong机器人#8 · 2017/8/29
【 在 mushroomboy 的大作中提到: 】 : 我在v2见过你,哈哈 被这个问题蛋疼到了,所以也去求助了下[em71]