golang爬虫 -- 采集需要登录账号的网站

因业务需求需要爬取大量网站的数据,有些网站是需要登录验证的。至此,记录一下本次用golang语言跳过千里马的登录验证流程以及一些坑

目标网站 : 千里马

登录接口以及参数解释 :
请求地址 : http://center.qianlima.com/login_post.jsp?re_url=null
请求方式 : POST
参数 :
username :用户名
password : 密码
rem_login : 不清楚是什么(截包发现传1)

下面是截取的http协议信息
golang爬虫 -- 采集需要登录账号的网站_第1张图片

golang源代码如下

package main

import (
“net/http”
URL “net/url”
“fmt”
“golang.org/x/text/encoding/simplifiedchinese”
“golang.org/x/text/transform”
“bytes”
“strings”
“net/http/cookiejar”
)

func main() {
    client := &http.Client{}
    var resp *http.Response
    req, err := http.NewRequest("POST", "http://center.qianlima.com/login_post.jsp?re_url=null",strings.NewReader("username=账号&password=密码&rem_login=1&Submit1="))

    if err != nil {
        return
    }

    client.Jar = jar

    req.Header.Set("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
    req.Header.Set("Accept-Encoding","")
    req.Header.Set("Cache-Control","max-age=0")
    req.Header.Set("Origin","http://center.qianlima.com")
    req.Header.Set("Accept-Language","zh-CN,zh;q=0.9")
    req.Header.Set("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36")
    req.Header.Set("Host","center.qianlima.com")
    req.Header.Set("Connection","keep-alive")
    req.Header.Set("Upgrade-Insecure-Requests","1")
    req.Header.Set("Content-Type","application/x-www-form-urlencoded")

    resp, err = client.Do(req)


    if(resp != nil && resp.Body != nil) {
        defer resp.Body.Close()
    } else {
        fmt.Println("ERROR http://center.qianlima.com/login_post.jsp?re_url=null 返回为空 ")
    }
    if resp == nil || resp.Body == nil || err != nil {
        return
    }

    // 打印所有请求头信息
    for k,v := range req.Header{
        fmt.Println("请求头信息 :",k,"=",v)
    }
    // 打印所有响应头信息
    for k,v := range resp.Header{
        fmt.Println("响应头信息 :",k,"=",v)
    }

    for _,v := range client.Jar.Cookies(req.URL){
        fmt.Println("响应头信息- :",v.Name,"=",v.Value)
    }
    // 打印正文信息
    var buf []byte
    buf, err = ioutil.ReadAll(resp.Body)
    if(err != nil) {
        return
    }

    buf,_ = gbk2utf8(buf)
    content := string(buf) 
    fmt.Println("正文信息:",content)
}
func gbk2utf8(str []byte) ([]byte,error) {
return ioutil.ReadAll(transform.NewReader(bytes.NewReader(str), simplifiedchinese.GBK.NewDecoder()))
}

记一个小坑 : 这个网站把Set-Cookie 分成几段发过来了,一开始用Response.Header 发现与截取的协议不匹配少了很多,在这个位置卡了很久
后来去翻了翻golang的源代码,发现Header是个map[string][]string
golang爬虫 -- 采集需要登录账号的网站_第2张图片
golang爬虫 -- 采集需要登录账号的网站_第3张图片
就想会不会被key相同被覆盖了,就去看了看请求方法Client.Do(req Request)

golang爬虫 -- 采集需要登录账号的网站_第4张图片

golang爬虫 -- 采集需要登录账号的网站_第5张图片
golang爬虫 -- 采集需要登录账号的网站_第6张图片
追溯到下面这个方法就可以找到解决方案了,如果Client.Jar != nil 会保留所有的cookie信息,在每次请求的时候带入这个Jar即可跳过登录验证
golang爬虫 -- 采集需要登录账号的网站_第7张图片


记于 2017年11月29日

你可能感兴趣的:(golang爬虫)