代理ip获取是用的付费的,免费的可用性和效率都太低了
首先是获取代理ip
//获取代理ip nowUseProxyIP :原来使用的ip
func getProxyIP(nowUseProxyIP string) string{
redisClient:=GetRedisClient()
defer redisClient.Close() //随手关闭
num ,_ := redisClient.Get("ProxyIP:"+nowUseProxyIP).Int()
//删除失败次数超过3次的ip
if num > 3{
if nowUseProxyIP!=""{
redisClient.SRem("ProxyIP", nowUseProxyIP )
}
}else{
num ++
duration, _ := time.ParseDuration("180s")
redisClient.Set("ProxyIP:"+nowUseProxyIP,Num,duration)
}
num, _ := redisClient.SCard("ProxyIP").Result()
if num > 1 {
ProxyIP , _ :=redisClient.SRandMember("ProxyIP").Result() //随机取一个
return ProxyIP
}
fmt.Println("===================" )
fmt.Println(" 【 创建代理池 】" )
fmt.Println("===================" )
requestUrl :="http://www.xxx.com/"
req, _ := http.NewRequest("GET", requestUrl, nil)
res, errs := http.DefaultClient.Do(req)
if errs != nil {
fmt.Println("代理请求失败", errs)
}
body, _ := ioutil.ReadAll(res.Body)
ipChan := make(chan interface{ })
arr := strings.Split(string(body), "\r\n")
for _,val := range arr{
//剔除不能用的ip
ipwg.Add(1)
go ProxyThorn( val , ipChan )
}
go func() {
ipwg.Wait()
close(ipChan)
}()
for val :=range ipChan{
if val.(string)!="" && val!=nil{
redisClient.SAdd("ProxyIP", val.(string))
}
}
ProxyIP , _ :=redisClient.SRandMember("ProxyIP").Result() //随机取一个
return ProxyIP
}
代理验证是否可用
//代理验证是否可用
func ProxyThorn(proxy_addr string ,ipChan chan interface{ }) {
//访问查看ip的一个网址
defer ipwg.Done()
httpUrl := "http://xxx.com/"
proxy, _ := url.Parse( "http://" +proxy_addr)
netTransport := &http.Transport{
Proxy:http.ProxyURL( proxy),
MaxIdleConnsPerHost: 10,
ResponseHeaderTimeout: time.Second * time.Duration(5),
}
httpClient := &http.Client{
Timeout: time.Second * 2,
Transport: netTransport,
}
res, err := httpClient.Get(httpUrl)
if err != nil {
return
}
if res.StatusCode != http.StatusOK {
return
}
if res.StatusCode==200 {
fmt.Println(proxy_addr + "-【检测结果:可用】")
ipChan <- proxy_addr
}
return
}
获取到ip过检测的存入redis集合中,在取的时候吧原来的代理ip做判断超过一定次数的删除代理池中的ip,并发爬虫的情况可以配合上 sync.Mutex
锁的使用,防止重复获取,这只是一个大概的一个思路,具体的还得按照自己的需求来做一下调整
有什么不对的地方还望大家指教