golang实现代理池获取及验证
在做爬虫时,ip被检测限制,应该是一个比较简单的后端访问异常限制的操作。对于爬虫来说,就不得不增加一个有效的IP代理池。网上许多免费的IP代理,连接性往往有待考证,需要通过验证代理点的可用性。所以一个批量检测生成代理ip的方式,可以让你更快获取有效的列表。
一、通过golang实现一个IP代理爬虫
这里的爬虫网址选用的是:西拉免费代理IP。
通过golang中的http请求目标接口,并对响应值进行页面解析。获取对应的td标签数据。
下面是golang实现代码:
package crawler
import (
"fmt"
"strconv"
"strings"
"sync"
"github.com/antchfx/htmlquery"
"github.com/kirinlabs/HttpRequest"
)
var (
Threads = make(chan int, 5) //控制在5以内
)
func Spider() map[int]string {
fmt.Println("等待爬虫程序数据爬取中。。。")
var wg sync.WaitGroup
var ip_port = make(map[int]string)
var num = 0
for i := 1; i < 2000; i++ {
Threads <- 1
wg.Add(1)
go func(i int) {
url := fmt.Sprintf("http://www.xiladaili.com/http/%d/", i)
res, _ := HttpRequest.Get(url)
defer res.Close()
body, _ := res.Body()
html := string(body)
root, _ := htmlquery.Parse(strings.NewReader(html))
tr := htmlquery.Find(root, "//tr")
for _, row := range tr {
item := htmlquery.Find(row, "//td")
if len(item) > 0 {
num++
ip := htmlquery.InnerText(item[0])
ip_port[num] = ip
}
}
defer wg.Add(-1)
<-Threads
}(i)
// time.Sleep(time.Second * 2)
}
wg.Wait()
return ip_port
}
二、构建一个代理请求验证
这步我们可以通过构建一个http请求,并为这个请求增加proxy代理,并对目标地址发出请求,通过验证响应信息,判断代理可用性。
下面是golang实现代码:
func IsProxy(proxyIp string, proxyPort int) (isProxy bool, err error) {
proxyUrl := fmt.Sprintf("http://%s:%d", proxyIp, proxyPort)
proxy, err := url.Parse(proxyUrl)
if err != nil {
return false, err
}
netTransport := &http.Transport{
Proxy: http.ProxyURL(proxy),
}
client := &http.Client{
Timeout: time.Second * 20, //设置连接超时时间
Transport: netTransport,
}
res, err := client.Get("http://www.baidu.com")
if err != nil {
return false, err
} else {
defer res.Body.Close()
if res.StatusCode == 200 {
body, err := ioutil.ReadAll(res.Body)
if err == nil && strings.Contains(string(body), "baidu") {
return true, nil
} else {
return false, err
}
} else {
return false, nil
}
}
}
三、构建main函数实现功能
通过main函数将爬虫与验证结合校验,并保存验证通过的代理ip。
package main
import (
"fmt"
"io"
"os"
"proxy_ip/crawler"
"proxy_ip/proxy"
"sync"
"time"
)
var (
Threads = make(chan int, 500)
)
func main() {
var wg sync.WaitGroup
var now = time.Now().Unix()
var Map = make(map[int]string)
ip_port := crawler.Spider()
var num = 0
for _, proxy := range ip_port {
Threads <- 1
wg.Add(1)
go func(proxy string) {
fmt.Printf("检测:%s\n", proxy)
isProxy, _ := proxy.IsProxy(proxy)
if isProxy {
num++
Map[num] = fmt.Sprintf("%s", proxyIp)
}
defer wg.Add(-1)
<-Threads
}(proxy)
}
wg.Wait()
fmt.Printf("用时%d秒\n", time.Now().Unix()-now)
fmt.Printf("爬虫共ip:%d个,可用共:%d个\n", len(ip_port), num)
writeTxt(Map)
fmt.Printf("程序将在%d后自动关闭。。。", 10)
time.Sleep(time.Second * 10)
}
func writeTxt(data map[int]string) {
filename := "proxy.txt"
var text = ""
if _, err := os.Stat(filename); os.IsNotExist(err) {
os.Create(filename)
}
for _, v := range data {
if text == "" {
text = fmt.Sprintf("%s", v)
} else {
text = fmt.Sprintf("%s\n%s", text, v)
}
}
f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_TRUNC, 0666)
_, _ = io.WriteString(f, text)
fmt.Println("代理文件创建完毕")
}
下面是我编译好的可执行文件下载地址,如有需要可自行跳转下载。
.exe程序下载地址