[Golang] 一个简易代理池
晚上写了一个代理池,就是在一个代理网站上爬取代理ip和端口以及测试是否可用。接下来可能考虑扩展成一个比较大的 golang实现的代理池。
简易版代码:
package main import (
"os"
"fmt"
log "github.com/Sirupsen/logrus"
"io/ioutil"
"strings"
) type New struct {
Prefix string
NewId string
Title string
Time string
Content string
Subject string
} type Subject struct {
Name string
Url string
} func CreateDir(PathName string) error {
err := os.Mkdir(PathName, 0777)
if err != nil && !os.IsExist(err) {
return err
}
return nil
} func AppendFile(SavePath string, FileName string, buf string) {
out, err := os.OpenFile(SavePath+FileName, os.O_WRONLY, 0644)
defer out.Close()
if err != nil {
log.Errorln(err.Error())
return
}
offset, err := out.Seek(0, os.SEEK_END)
if err != nil {
log.Errorln(err.Error())
return
}
_, err = out.WriteAt([]byte(buf), offset)
if err != nil {
log.Errorln(err.Error())
return
}
log.Warnln("Save file finished. Locate in ", SavePath + FileName)
} func PathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
} func SaveFile(SavePath string, FileName string, buf string) {
out, err := os.Create(SavePath + FileName)
defer out.Close()
fmt.Fprintf(out, "%s", buf)
if err != nil {
log.Errorln(err.Error())
return
}
log.Warnln("Save file finished. Locate in ", SavePath + FileName)
} func ReadAll(path string) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
return ioutil.ReadAll(f)
} func ReadFile(path string) []string {
var fp interface{}
fp, err := ReadAll(path)
if err != nil {
log.Errorln(err.Error())
return nil
}
fp = string(fp.([]byte))
return strings.Split(fp.(string), "\n")
}
package main import (
log "github.com/Sirupsen/logrus"
"math/rand"
"net/http"
"net/url"
"time"
) var userAgent = [...]string {
"Mozilla/5.0 (compatible, MSIE 10.0, Windows NT, DigExt)",
"Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, 360SE)",
"Mozilla/4.0 (compatible, MSIE 8.0, Windows NT 6.0, Trident/4.0)",
"Mozilla/5.0 (compatible, MSIE 9.0, Windows NT 6.1, Trident/5.0,",
"Opera/9.80 (Windows NT 6.1, U, en) Presto/2.8.131 Version/11.11",
"Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, TencentTraveler 4.0)",
"Mozilla/5.0 (Windows, U, Windows NT 6.1, en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Macintosh, Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
"Mozilla/5.0 (Macintosh, U, Intel Mac OS X 10_6_8, en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Linux, U, Android 3.0, en-us, Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
"Mozilla/5.0 (iPad, U, CPU OS 4_3_3 like Mac OS X, en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
"Mozilla/4.0 (compatible, MSIE 7.0, Windows NT 5.1, Trident/4.0, SE 2.X MetaSr 1.0, SE 2.X MetaSr 1.0, .NET CLR 2.0.50727, SE 2.X MetaSr 1.0)",
"Mozilla/5.0 (iPhone, U, CPU iPhone OS 4_3_3 like Mac OS X, en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
"MQQBrowser/26 Mozilla/5.0 (Linux, U, Android 2.3.7, zh-cn, MB200 Build/GRJ22, CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
} func GetRandomUserAgent() string {
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
return userAgent[r.Intn(len(userAgent))]
} func GetFakeHeader(request *http.Request) {
request.Header.Set("User-Agent", GetRandomUserAgent())
request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
request.Header.Set("Connection", "keep-alive")
//request.Header.Set("Accept-Encoding", "gzip, deflate")
} func GetByProxy(proxyAddr string, Url string) (*http.Response, error) {
timeout := time.Duration(10 * time.Second)
request, err := http.NewRequest(http.MethodGet, Url, nil)
GetFakeHeader(request)
if err != nil {
return nil, err
}
proxy, err := url.Parse(proxyAddr)
if err != nil {
log.Errorln(err.Error())
}
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxy),
},
Timeout: timeout,
}
return client.Do(request)
} func GetByDirectory(Url string) (*http.Response, error) {
timeout := time.Duration(10 * time.Second)
request, err := http.NewRequest(http.MethodGet, Url, nil)
GetFakeHeader(request)
if err != nil {
return nil, err
}
client := http.Client{
Timeout: timeout,
}
return client.Do(request)
}
package main import (
log "github.com/Sirupsen/logrus"
"strconv"
"regexp"
"github.com/opesun/goquery"
"time"
) const (
SAVE_PATH = "kproxy.orz"
PROXY_URL = "http://www.kuaidaili.com/free/inha/"
)
var (
IP_REGEXP = regexp.MustCompile(`[\d]+\.[\d]+\.[\d]+\.[\d]+\n\s+[\d]+`)
IP_DETAIL_REGEXP = regexp.MustCompile(`[\d]+\.[\d]+\.[\d]+\.[\d]+`)
INT_REGEXP = regexp.MustCompile(`\s[\d]+`)
) func UrlGetter(num int) string {
return PROXY_URL + strconv.Itoa(num)
} func GetProxy(Url string) {
nod, err := goquery.ParseUrl(Url)
if err != nil {
log.Errorln(err.Error())
return
}
ret := nod.Text()
ips := IP_REGEXP.FindAll([]byte(ret), -1)
var port []string = make([]string, len(ips))
var str string = ""
for i := 0; i < len(ips); i++ {
port[i] = string(INT_REGEXP.FindAll(ips[i], -1)[0])[1:]
ips[i] = IP_DETAIL_REGEXP.FindAll(ips[i], -1)[0]
str += string(ips[i])+":"+port[i]+"\n"
}
AppendFile("./", SAVE_PATH, str)
} func main() {
log.Infoln("Start getting proxy ...")
SaveFile("./", SAVE_PATH, "")
for i := 1; i <= 500; i++ {
log.Println(UrlGetter(i))
GetProxy(UrlGetter(i))
time.Sleep(time.Second*5)
}
}
这里有个python来测试:
import urllib
import urllib2
import os
import socket AIM_URL = ''
PROXY_PATH = './kproxy.orz' class MyException(Exception):
pass def read_file(path):
if not os.path.exists(path):
print 'path : \''+ path + '\' not find.'
return []
content = ''
try:
with open(path, 'r') as fp:
content += reduce(lambda x,y:x+y, fp)
finally:
fp.close()
return content.split('\n') socket.setdefaulttimeout(5)
proxies = read_file(PROXY_PATH)
print len(proxies)
for pp in proxies:
try:
print 'http://'+pp
inforMation = urllib.urlopen(AIM_URL, proxies={'http': 'http://'+pp})
except urllib2.URLError, e:
if isinstance(e.reason, socket.timeout):
pass
except:
pass
finally:
pass
[Golang] 一个简易代理池的更多相关文章
- 基于Win32 SDK实现的一个简易线程池
利用C++实现了一个简易的线程池模型(基于Win32 SDK),方便使用多线程处理任务.共包含Thread.h.Thread.cpp.ThreadPool.h.ThreadPool.cpp四个源文件. ...
- 一个简易内存池(C++)
做这个内存池主要是为了完成一道面试题,题目在代码中. 代码 #include <iostream> #include<string> #include <list> ...
- Python实现的异步代理爬虫及代理池
使用python asyncio实现了一个异步代理池,根据规则爬取代理网站上的免费代理,在验证其有效后存入redis中,定期扩展代理的数量并检验池中代理的有效性,移除失效的代理.同时用aiohttp实 ...
- 使用redis所维护的代理池抓取微信文章
搜狗搜索可以直接搜索微信文章,本次就是利用搜狗搜搜出微信文章,获得详细的文章url来得到文章的信息.并把我们感兴趣的内容存入到mongodb中. 因为搜狗搜索微信文章的反爬虫比较强,经常封IP,所以要 ...
- python开源IP代理池--IPProxys
今天博客开始继续更新,谢谢大家对我的关注和支持.这几天一直是在写一个ip代理池的开源项目.通过前几篇的博客,我们可以了解到突破反爬虫机制的一个重要举措就是代理ip.拥有庞大稳定的ip代理,在爬虫工作中 ...
- python爬虫18 | 就算你被封了也能继续爬,使用IP代理池伪装你的IP地址,让IP飘一会
我们上次说了伪装头部 ↓ python爬虫17 | 听说你又被封 ip 了,你要学会伪装好自己,这次说说伪装你的头部 让自己的 python 爬虫假装是浏览器 小帅b主要是想让你知道 在爬取网站的时候 ...
- 【解决方案】IP代理池设计与解决方案
一.背景 爬虫服务请求量大,为了应对反爬措施,增加爬虫的爬取效率和代理IP使用率,需要设计一个IP代理池,满足以下需求: 定时任务获取第三方代理 及时剔除IP代理池中失效的IP 业务隔离IP 若IP未 ...
- 用golang 实现一个代理池
背景 写爬虫的时候总会遇到爬取速度过快而被封IP的情况,这个时候就需要使用代理了.在https://github.com/henson/ProxyPool 的启发下,决定自己实现一个代理池.项目已经开 ...
- 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫
前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,本文记录免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作 ...
随机推荐
- IOS第18天(2,CALayer自定义图层)
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...
- array_diff的参数前后循序的区别
//如果两个参数之间有区别.array_diff会返回第二个参数的差值 $oldData = array(0=>'德国',1=>'deguo'); $newData = array(0=& ...
- js滚动加载插件
function $xhyload(o){ var that=this; if(!o){ return; }else{ that.win=$(o.config.obj); that.qpanel=$( ...
- Geolocation
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Redis配置文件(redis.conf)说明
Redis 配置 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONFIG 命令查看或设置配置项. 语法3> Redis CONFIG 命令 ...
- sdk 更新的时连接不上dl-ssl.google.com解决办法
今天有朋友说sdk的更新不了,借了个VPN给他也没解决问题,后来还是他自己解决了,下面分享下经验 这里介绍一种不需要FQ的解决办法,修改C:\Windows\System32\drivers\etc下 ...
- Oracle的Connect By理解
connect by中的条件就表示了父子之间的连接关系 比如 connect by id=prior pid,但如果connect by中的条件没有表示记录之间的父子关系那会出现什么情况? 常见的,c ...
- [SLAM] GMapping SLAM源码阅读(草稿)
目前可以从很多地方得到RBPF的代码,主要看的是Cyrill Stachniss的代码,据此进行理解. Author:Giorgio Grisetti; Cyrill Stachniss http: ...
- [PCL]ApproximateVoxelGrid
点云滤波继承自Filter模板类 注意Filter类的filter 方法调用了虚方法applyFilter: inline void filter (PointCloud &output) { ...
- IDEA14下多jdk编译时,enum不支持;多个project共用在一个workplace下每个module时引用外部包
idea多个工程如何在一个项目中管理: 把多个多个项目放在一个叫work目录下,那么打开IntelliJ IDEA编译器,点击菜单 File->Open...,选择刚刚的work目录,即可. 在 ...