我05年写的 perl/shell 配合程序,用于生成自动代理脚本,(从教育网)访问国内不用代理,访问国外用速度测试比较快的代理,介绍文章不是很充分,是当时的两篇blog,凑和看吧。话说后来出了教育网直通车,免费代理就很少有好用的了,这其中的缘由不必多说了哈。
http://gnawux.bokee.com/1051393.html
http://gnawux.bokee.com/1078944.html
首先给个宏观的印象
wget -q http://proxy.ipcn.org/proxylist -O - |grep "^[0-9]" | \
./tp.pl www.google.com | sort -n | cut -f2
首先通过 wget 获取网页上的代理列表并清除其它的东西,剩下的比较纯粹,
是这样的:
61.138.10.125:8080
61.145.73.211:80
61.145.73.220:80
61.150.115.245:8080
61.172.253.130:8080
61.178.185.55:80
61.189.235.207:8080
202.101.32.9:80
202.103.69.53:808
202.110.216.172:8080
然后用自己写的 perl 脚本逐一测试,输出是这样的:
1 61.138.10.125:8080
11 61.145.73.211:80
5 61.145.73.220:80
12 61.150.115.245:8080
12 61.189.235.207:8080
8 211.101.:8080
9 211.98.24.6:8080
7 218.28.135.196:8080
6 218.76.51.3:8080
10 219.147.36.253:8080
12 219.149.211.118:8080
第一列是时延值,作为以后的判决依据,当然,这里保留了可扩展性,将来
还可以有更复杂的判据,但用数值输出。然后用 sort 算术排序一下,就是
这样的了
0 61.138.10.125:8080
1 202.110.216.172:8080
3 218.28.135.196:8080
4 61.150.115.245:8080
6 61.145.73.220:80
7 211.98.24.6:8080
7 219.149.233.179:8080
7 61.189.235.207:8080
8 218.56.32.230:8080
10 218.76.51.3:8080
11 211.101.:8080
15 61.145.73.211:80
最后取出第二个字段,也就是排好序的代理列表了
附--自制的代理测试脚本:
#!/usr/bin/perl -w
use IO::Socket;
#上面这个引用 socket 模块
my $dest=inet_ntoa(inet_aton("$ARGV[0]"));
my $proxy=$ARGV[1];
#用于测试的目标地址,我用了 google
$SIG{ALRM}=\&timeout;
#指定子函数timeout 处理 ALRM 信号,这样超时就不会退出程序了。
while(){ #从标准输入读入代理(实际是管道过来的)
chomp;
($p_host,$p_port)=split /:/;
#分成主机名和端口两部分
my $time1=time; #第一次计时
$sock = new IO::Socket::INET (PeerAddr => $p_host,
PeerPort => $p_port,
Proto => 'tcp',
Timeout => 6
);
#打开一个socket
if($sock){
my $time2=time; # 第二次计时
my $mesg="GET http://$dest HTTP/1.1
Host: $dest
Accept: */*
Pragma: no-cache
User-Agent: aptitude.bbs\@bupt.org\n\n";
$sock->print("$mesg");
#向代理服务器请求google
alarm(10);
my $buffer=$sock->getline();
alarm(0);
#等待代理响应,用alarm防止超时,超时会发出 ALRM 信号
if(! $buffer){next;} #如果没有响应就算了
my $time3=time; #如果有响应,第三次计时
chop($buffer);
if($buffer =~ /HTTP\/1\.1 200 OK/){ #如果连接成功
my $ct=$time2-$time1; # 连接代理时间
my $rt=$time3-$time2; # 请求响应时间
my $td=$ct+$rt;
# 总时间,这个度量可以加入权重,我还不知道怎么加比较合理,所以
# 先直接算术求和了
print "$td\t$p_host:$p_port\n"; # 输出
}
close($sock); # 关掉 socket
}}
exit;
sub timeout{
# print STDERR "timeout\n";
$sock->shutdown(2);
# I/O 超时则直接关闭 socket
}
就这样吧,下一步是和免费 IP 列表结合起来做一个自动代理脚本,mozilla 就方便了
整个自动代理生成程序共6个文件:
*-> proxy.sh 这个是主程序(shell)
*-> tp.pl 这个是用来测试代理响应时间的(perl)
*-> gap.pl 这个是用来根据已经有的代理列表和CERNET免费IP列表生成自动代理脚本的(也是perl)
*-> sorted-proxy.list 这个是中间文件,按响应时间顺序排列的可用代理列表,由tp.pl的输出经过简单处理生成
*-> freeip.list 这个是cernet公布的免费IP列表,你也可以下载到,不是什么机密
*-> autoproxy.pac 就是自动生成的自动代理列表了,由gap.pl生成
其中核心部分已经在前面里说完了,略有改动,不大,这次这个是自动代理脚本的生成:
===
#!/usr/bin/perl -w
print("function FindProxyForURL(url,host){
if(isPlainHostName(host)||
dnsDomainIs(host,\".ieee.org\")||
isInNet(host,\"127.0.0.1\",\"255.255.255.255\")||
isInNet(host,\"192.168.10.0\",\"255.255.255.0\"))
return \"DIRECT\"\;\n");
my $freelist=shift;
my $proxylist=shift;
open(FREEIP,"<$freelist");
while(){
chomp;
my $f_addr;
my $f_set; #trivial
my $f_mask;
($f_addr,$f_set,$f_mask)=split;
print("else if(isInNet(host,\"$f_addr\",\"$f_mask\"))
return \"DIRECT\"\;\n");
}
close(FREEIP);
open(PROXY,"<$proxylist");
print(
"else
return \"");
while(){
chomp;
if($_){
print("PROXY $_\; ");
}
}
print("DIRECT \"\;
}\n");