使用 Golang 写爬虫经验总结

您所在的位置:网站首页 go语言爬虫教程 使用 Golang 写爬虫经验总结

使用 Golang 写爬虫经验总结

2024-07-16 03:49| 来源: 网络整理| 查看: 265

模拟登录

模拟登录最重要的是保存cookies的状态,例如在填写验证码的页面,服务器会传给客户端一个sessionID保存在cookies中,客户端在提交用户账户和验证码等信息时,需要连同这个cookies一起提交,否则服务器就无法判断两次请求是否为同一个客户端,从而导致验证码验证失败。 在Golang中可以使用CookieJar管理cookies,在创建http.Client的对象时,传入一个非空的CookieJar对象即可。设置了之后,Golang在收到服务器的响应之后,会自动把响应头中的cookies信息保存到CookieJar中,在下次发起请求时,自动从CookieJar中取出cookies信息放到请求头中。

// &cookiejar.Options{PublicSuffixList: publicsuffix.List},这是为了可以根据域名安全地设置cookies cookieJar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) if err != nil { panic(err) } client = http.Client{Jar: cookieJar, Timeout: time.Second * 3} POST提交

GET提交方式很简单,直接拼接字符串就行了。POST提交需要一个可读的(io.Reader)请求体body,body中是形如a=b&c=d格式的查询字符串(字节切片)。可以借助url.Values方便的生成查询字符串,它本质是一个map[string][]string,提供了Set,Add等方法,让操作这个map更简单。

params := url.Values{} // 添加参数 params.Add("memberAccount", "xxx") // 添加sha1后的参数 params.Add("memberUmm", fmt.Sprintf("%x", sha1.Sum([]byte("xxxx")))) params.Add("check", captcha) params.Add("rememberMe", "on") // 1.必须设置正确的Content-Type,否则服务器无法正确识别参数 // 2.params.Encode()生成查询字符串,然后用string.NewReader包裹这个字符串使其可读 res, err := client.Post("https://www.example.com/login.json", "application/x-www-form-urlencoded", strings.NewReader(params.Encode())) if err != nil { return "", err } // 记得关闭 defer res.Body.Close() 上传文件

上传文件需要借助multipart.Writer向请求体中写入相应的数据,使用multipart.NewWriter生成这样的一个写入器,它接收一个io.Writer作参数,这个参数即我们的表单体body,body除了需要可写,还要可读(让httpClient读取参数发送到服务器),并且它是流式的,所以选用bytes.Buffer,一个可读写大小可变的字节流缓冲器。

body := new(bytes.Buffer) // 创建body的写入器 mulWriter := multipart.NewWriter(body) 写入普通字段 // 直接调用writeField方法即可,参数1是参数名,参数2是参数值 err := mulWriter.WriteField("user_name", "xxx") if err != nil { return "", err } 写入文件字段

要写入文件,需要先调用CreateFormFile创建一个文件内容写入器,再通过写入器写入文件的内容

// 创建文件写入器,并指明文件参数名和参数值 fileWriter, err := mulWriter.CreateFormFile("upload", filepath.Base(filename)) if err != nil { return "", err } // 打开需要上传的文件 file, err := os.Open(filename) if err != nil { return "", err } defer file.Close() // 复制文件内容到写入器 _, err = io.Copy(fileWriter, file) if err != nil { return "", err } // 记得关闭,让缓冲区的内容写入body中 err = mulWriter.Close() if err != nil { return "", err } res, err := client.Post("http://v1-http-api.jsdama.com/api.php?mod=php&act=upload", mulWriter.FormDataContentType(), body)

上面例子的最后一行,必须使用FormDataContentType()方法获取正确的Content-Type,而不能自己写multipart/form-data,这是因为boundary是随机生成的,这个必须由Golang告诉我们正确的值。boundary即表单体中分隔每个参数的一个标志位,如下图:

使用 Golang 写爬虫经验总结

使用Fiddler调试程序

使用Fiddler抓包可以让我们方便的看到程序提交到服务器的数据格式,使得调试和修改程序更加简单。Fiddler相当于一个正向代理服务器,启动后,它会把IE的代理服务器设置为http://127.0.0.1:8888 ,即Fiddler默认的代理地址,这样所有浏览器的请求都会先通过Fiddler,再由Fiddler转发出去,实现抓包。 但是上面的机制只对系统的浏览器有效,要对其他程序也生效,需要单独的设置程序的代理。 Golang设置代理比较简单,只需要增加一个环境变量设置即可,可以修改系统的环境变量,也可以通过代码动态添加。

// 设置httpClient的代理 os.Setenv("HTTP_PROXY", "http://127.0.0.1:8888") 解决HTTPS解密失败的问题

如果Fiddler出现无法解密HTTPS请求,看不到原始请求数据的情况,可以尝试重新安装Fiddler的根证书来解决。具体操作:

打开Fiddler,依次点击菜单Tools->Options,打开设置对话框,点击选中"HTTPS"面板

使用 Golang 写爬虫经验总结

取消“Decrypt HTTPS traffic”的选中状态,点击“Actions”按钮,点击“Reset All Certificates”,之后会弹出确认框问你是否要删除当前的证书并创建新的证书,一路允许即可

使用 Golang 写爬虫经验总结

fiddler 爬虫 本作品采用《CC 协议》,转载必须注明作者和本文链接


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3