### 快代理
goquery包github地址:https://github.com/PuerkitoBio/goquery
快代理:https://www.kuaidaili.com/free/
ip地址查询api接口:http://vv.video.qq.com/checktime?otype=json
运行结果:
![](https://img.kancloud.cn/bc/14/bc148a314d950481c81449bf2d12e1ea_1193x501.png)
这个报错是因为有变量指向nli了
![](https://img.kancloud.cn/d3/f8/d3f8a0fcbe8440e26c9697db3c27558a_775x74.png)
ip地址查询api接口
1. 搜狐:https://pv.sohu.com/cityjson?ie=utf-8
2. 网易:http://ip.ws.126.net/ipquery?ip=114.114.114.114
3. 天翼:https://cloud.189.cn/ip/getIp.do
4. 腾讯:http://vv.video.qq.com/checktime?otype=json
5. 高德:https://restapi.amap.com/v3/ip?key=0113a13c88697dcea6a445584d535837&ip=39.156.69.79
6. B站:https://api.bilibili.com/x/web-interface/zone?jsonp=jsonp
7. 太平洋:http://whois.pconline.com.cn/ip.jsp?ip=114.114.114.114
8. IPAPI:http://ip-api.com/json/114.114.114.114?lang=zh-CN
参考:https://blog.csdn.net/qq_39116404/article/details/105346644
参考:https://blog.csdn.net/weixin_33936401/article/details/89582308?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=2
Find()选择器用法参考:https://www.cnblogs.com/chaoyueqi/p/7545837.html
完整案列:
```
// by 安研 记性不好 只能多写注释
package main
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"time"
"github.com/PuerkitoBio/goquery"
)
// 使用结构体 来解码 编码json数据 和用来接收爬取的数据
type Presult struct {
Ip string `json:"ip"` // ip
Port string `json:"port"` // port 端口
Anonymous string `json:"anonymous"` // 匿名度
Agreement string `json:"agreement"` //类型
Region string `json:"region"` //地区
Speed string `json:"speed"` //速度
Timeout string `json:"timeout"` //最后验证时间
}
// 采集代理ip数据
func Collection(Url string) []Presult {
// 用这个结构体储存 请求返回的结果
proxyList := []Presult{}
// 创建一个请求客户端
client := &http.Client{}
// 设置发起请求参数
re, err := http.NewRequest("GET", Url, nil)
// 错误处理
if err != nil {
fmt.Println(err)
}
// 设置请求头 不设置请求头会请求失败
re.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36")
// 发起请求
resp, err := client.Do(re)
// 错误处理
if err != nil {
fmt.Println(err)
}
// 响应处理
if resp.StatusCode != 200 {
fmt.Println("请求失败")
}
// 使用goquery 的方法 返回网站的html文档
doc, err := goquery.NewDocumentFromReader(resp.Body)
//错误处理
if err != nil {
fmt.Println(err)
}
// 根据标签和节点匹配到需要的内容
doc.Find("table tbody tr").Each(func(i int, s *goquery.Selection) {
ip := s.Find("td[data-title=IP]").Text() // ip
port := s.Find("td[data-title=PORT]").Text() //端口
anonymous := s.Find("td[data-title=匿名度]").Text() //匿名度
agreement := s.Find("td[data-title=类型]").Text() //类型
region := s.Find("td[data-title=位置]").Text() // 位置
speed := s.Find("td[data-title=响应速度]").Text() //响应速度
timeout := s.Find("td[data-title=最后验证时间]").Text() // 最后验证时间
// fmt.Println(ip, port, anonymous, agreement, region, speed, timeout) //检查一下
proxyList = append(proxyList, Presult{
Ip: ip, //ip
Port: port, // port 端口
Anonymous: anonymous, // 匿名度
Agreement: agreement, //类型
Region: region, //地区
Speed: speed, //速度
Timeout: timeout, //最后验证时间
})
})
// 输出 这个结构体
return proxyList
}
// 发起请求 测试ip
func Requestproxy(proxyList []Presult, httpurl string) {
//fmt.Println(proxyList)
for _, p := range proxyList {
// 根据不同协议 测试
if p.Agreement == "HTTP" {
// 整理采集到的ip,输出成 http://111.160.169.54:41820 协议 ip 端口 这种形式
proxyip := "http://" + p.Ip + ":" + p.Port
// 这里是请求对象 是一个 检查访问ip 返回的网站
httpurl := httpurl
// 格式化 代理ip
proxy, err := url.Parse(proxyip)
// 错误处理
if err != nil {
fmt.Println(err)
}
// 主要设置请求的代理ip 时长
netTransport := &http.Transport{
Proxy: http.ProxyURL(proxy),
Dial: func(netw, addr string) (net.Conn, error) {
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(10))
if err != nil {
return nil, err
}
return c, nil
},
MaxIdleConnsPerHost: 10, //每个host最大空闲连接
ResponseHeaderTimeout: time.Second * time.Duration(5), //数据收发5秒超时
}
httpClient := &http.Client{
Timeout: time.Second * 10,
Transport: netTransport,
}
// 使用设置的代理ip 发起 get请求
res, err := httpClient.Get(httpurl)
if err != nil {
fmt.Println("ip:" + p.Ip + ",请求超时")
}
// 这里 res 可能是 nil 如果是nil 就会报错panic: runtime error: invalid memory address or nil pointer dereference 变量不能指向nil
if res == nil {
fmt.Println("ip:" + p.Ip + ",请求超时")
} else {
// 关闭请求体 释放资源
defer res.Body.Close()
//解析 收到的数据
body, _ := ioutil.ReadAll(res.Body)
//输出
fmt.Println(string(body))
}
// 如果协议不是http 就会执行这里的。这里省略
} else if p.Agreement == "HTTPS" {
proxyip := "https://" + p.Ip + ":" + p.Port
fmt.Println(proxyip)
}
}
}
func main() {
proxyList := Collection("https://www.kuaidaili.com/free/")
Requestproxy(proxyList, "http://vv.video.qq.com/checktime?otype=json")
}
```
- 安装开发环境
- 安装开发环境
- 安装详细教程
- 引入包
- Go语言基础
- 基本变量与数据类型
- 变量
- 数据类型
- 指针
- 字符串
- 代码总结
- 常量与运算符
- 常量
- 运算符
- 流程控制
- if判断
- for循环
- switch分支
- goto跳转
- 斐波那契数列
- Go语言内置容器
- 数组
- 切片
- 映射
- 函数
- 函数(上)
- 函数(中)
- 函数(下)
- 小节
- 包管理
- 结构体
- 结构体(上)
- 结构体(中)
- 结构体(下)
- 小节
- 错误处理
- 错误处理
- 宕机
- 错误应用
- 小节
- 文件操作
- 获取目录
- 创建和删除目录
- 文件基本操作(上)
- 文件基本操作(中)
- 文件基本操作(下)
- 处理JSON文件
- 接口与类型
- 接口的创建与实现
- 接口赋值
- 接口嵌入
- 空接口
- 类型断言(1)
- 类型断言(2)
- 小节
- 并发与通道
- goroutine协程
- runtime包
- 通道channel
- 单向通道channel
- select
- 线程同步
- 多线程的深入学习
- http编程
- http简介
- Client和Request
- get请求
- post请求
- 模块函数方法
- 模块
- fmt库,模块
- 项目练习
- 爬虫:高三网
- 爬虫:快代理
- 爬虫:快代理2
- 多线程:通道思路
- 多线程爬虫:快代理