golang实现代理池批量获取及验证

   日期:2020-08-08     浏览:93    评论:0    
核心提示:golang实现代理池获取及验证​ 在做爬虫时,ip被检测限制,应该是一个比较简单的后端访问异常限制的操作。对于爬虫来说,就不得不增加一个有效的IP代理池。网上许多免费的IP代理,连接性往往有待考证,需要通过验证代理点的可用性。所以一个批量检测生成代理ip的方式,可以让你更快获取有效的列表。一、通过golang实现一个IP代理爬虫这里的爬虫网址选用的是:西拉免费代理IP。通过golang中的http请求目标接口,并对响应值进行页面解析。获取对应的td标签数据。下面是golang实现代码:pac

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程序下载地址

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服