LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1428|回复: 4

linux下全自动化的代理解决方案

[复制链接]
发表于 2005-11-19 02:54:38 | 显示全部楼层 |阅读模式
也许很多人会抱怨为什么linux下就没有像windows中花刺那样方便的代理工具。其实GNU/linux系统是个百宝箱,只要稍稍用心就可以将它们组合成为一件比花刺更方便、更实用的代理武器。

第一个脚本文件getproxy.sh会自动从华中在线和西交共享的代理发布页上下载并生成代理列表。随后它会调用第二个脚本文件 checkproxy.sh来验证代理列表中的代理,并在用户主目录下生成一个按代理速度排序的.proxies文件。
说明1:getproxy.sh中选取的是适用于教育网的代理发布页。
说明2:西交共享的代理发布页面比较变态,需要使用post方法才能下载,而且post的数据又超长无比,这堆垃圾就不必附上了。需要的话可以使用firefox配合httpheader扩展很方便的抓取到post的数据,然后再在代码中做相应的更改就可以了。

我能想到的最佳使用方法是将 getproxy.sh加到cron中去,让它在后台每3小时自动执行一次:

[PHP]30 */3 * * *    $HOME/bin/getproxy.sh[/PHP]
这样我们就可以得到一个每3小时自动更新的代理列表了。但更重要的是在web 浏览器中使用它。

firefox 下很一些很不错的管理代理的扩展,我推荐使用国人写的xyzproxy。xyzproxy可以手工导入主目录下的.proxies文件,但显然这还不够方便。我希望它能够定时从这个文件来读入代理,并自动使用响应最快的那个代理。可惜目前xyzproxy还没有这个功能。好在GNU工具都有源代码可看,只要愿意动手一切问题都可解决。

我的解决方案还好丑陋,完全是现学现改,还属于ugly hack的阶段。不过目前看来这已完全达到我需要的效果了。

主要是要修改xyzproxy扩展目录下xyzproxy.js中的相应代码。首先在文件头中添加两行定义:

[PHP] var timer=null;
var observer = {
     observe :function(aSubject, aTopic, aData){
         xyzproxyReload();
     }
}[/PHP]
在xyzproxyInit函数的结尾处加入下面的语句,其中的延时参数7200000为2小时,请酌情更改。
[PHP]     xyzproxyReload();
     timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);

     timer.init(observer, 7200000,timer.TYPE_REPEATING_SLACK);[/PHP]

xyzproxyReload函数基本是照抄xyzproxyImport,只是添加了文件读取的路径、设置使用第一个读入的代理及最多读取10个代理。这些也请酌情处理。注意:其中设置文件读取路径的地方必须使用全路径,请将其中的ybyygu字样替换自己的用户名。

[PHP]function xyzproxyReload(){
     InitDataSource();

     //Get proxy list
     var oFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
     oFile.initWithPath("/home/ybyygu/.proxies");

     var oFileStream   = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
       oFileStream.init(oFile, 0x01, 00440, null);
     var oScriptStream   = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
       oScriptStream.init(oFileStream);
     
     var sProxyList = oScriptStream.read(oScriptStream.available());

     //Split Proxy List
     aProxies = sProxyList.split("\n");

     //清空RDF
     xyzProxyEmptyProxyRDF();
     //清空菜单
     xyzProxyEmptyProxyUIList();

     var j=0;
     for(var i=0;i<aProxies.length;i++){
         aProxies=xyzProxytrim(aProxies);
         if(aProxies.length<=1){
             continue;//去除空行
         }
         var aProxy=xyzProxySplitDomain(aProxies);
         var aUri=xyzProxyGetUniqueProxyUri();
         
         // Auto select the first one
         if (j++==0) setproxy(aProxy[0], aProxy[1]);

         if (j>10) break;

         //放入rdf
         var tmpProxyRes=gXyzProxyRdfService.GetResource(aUri);
         gXyzProxyRdfContainer.AppendElement(tmpProxyRes);
         var oProp;
         oProp= gXyzProxyRdfService.GetResource(gRdfProxyPropRoot + "#networkProxyHTTP");
         xyzProxyAddProperty(tmpProxyRes,oProp,aProxy[0],true);
         oProp= gXyzProxyRdfService.GetResource(gRdfProxyPropRoot+"#networkProxyHTTP_Port");
         xyzProxyAddProperty(tmpProxyRes,oProp,aProxy[1],true);

         if(aProxy[2]!=null){
             oProp= gXyzProxyRdfService.GetResource(gRdfProxyPropRoot+"#name");
             xyzProxyAddProperty(tmpProxyRes,oProp,aProxy[2],true);
         }

         AppendToProxyListUI( aProxy[2], aUri, aProxy[0], aProxy[1], false,0);
     }

     UpdateMenuListCheckedUI();
}
[/PHP]

第一个bash脚本:getproxy.sh

[PHP]#!/bin/bash
#===============================================================================
#
#         FILE:  getproxy.sh
#
#        USAGE:  ./getproxy.sh
#
#  DESCRIPTION:  download proxylist from web
#
#      OPTIONS:  ---none
# REQUIREMENTS:  ---curl, w3m
#         BUGS:  ---
#        NOTES:  ---add this command to cron job list
#       AUTHOR:   (ybyygu)
#      COMPANY:  
#      VERSION:  1.0
#      CREATED:  2005年11月18日 14时43分06秒 CST
#     REVISION:  ---
#===============================================================================

# Where we save the proxylist?
list=$HOME/.proxylist

temp=$(mktemp)

download(){
     url=$1

     if (($#==2));then
         data=$2
     fi

     html=$(mktemp)
     if (($#==1));then
         curl $url -o $html && w3m -dump -T "text/html" $html>>$temp
     elif (($#==2));then
         curl --data $data $url -o $html && w3m -dump -T "text/html" $html>>$temp
     fi

     if [ -f $html ];then
         rm $html
     fi
}

# hustu online
(download "http://info.hustonline.net/index/proxyshow.aspx") &

# downloading xjtushare's web page need special method
postdata=$HOME/.post.data
data=`cat ~/.post.data`
(download "http://www.xjtushare.com/proxy.aspx" $data) &

# wait for background jobs done
wait

egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]+' $temp|sort|uniq>/tmp/proxy.list

if [ -f $temp ];then
     rm $temp
fi


# if proxies less than 5, discard it.
count=`cat /tmp/proxy.list|wc -l`
if (($count>5));then
     mv /tmp/proxy.list $list
     $HOME/bin/checkproxy.sh
fi[/PHP]


第二个bash脚本checkproxy.sh

[PHP]#!/bin/bash
#===============================================================================
#
#         FILE:  checkproxy.sh
#
#        USAGE:  ./checkproxy.sh
#
#  DESCRIPTION:  check proxies from proxylist
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---curl
#         BUGS:  ---??
#        NOTES:  ---place this script in ~/bin
#       AUTHOR:   (ybyygu)
#      COMPANY:#===============================================================================
#
#         FILE:  checkproxy.sh
#
#        USAGE:  ./checkproxy.sh
#
#  DESCRIPTION:  check proxies from proxylist
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---curl
#         BUGS:  ---??
#        NOTES:  ---place this script in ~/bin
#       AUTHOR:   (ybyygu)
#      COMPANY:
#      VERSION:  1.0
#      CREATED:  11/19/05 01:46:18 CST
#     REVISION:  ---
#===============================================================================

check()
{
     proxy_host=$1
     proxy_port=$2
     timeout=30
     url='http://www.ubuntulinux.org/'
     
#      VERSION:  1.0
#      CREATED:  11/19/05 01:46:18 CST
#     REVISION:  ---
#===============================================================================

check()
{
     proxy_host=$1
     proxy_port=$2
     timeout=30
     url='http://www.ubuntulinux.org/'
     
     # use -m option to specify timeout seconds
     # use -i option to dump the header into output
     # use -L option to follow http redirection
     state=$(mktemp)
     response_time=$(/usr/bin/time -o /dev/stdout -f "%e" curl --stderr /dev/null -m $timeout -x "$proxy_hostproxy_port" $url -o $state)

     if [ -z "$response_time" ];then
         exit 1
     fi

     if [ "$(echo $response_time|egrep '[^0-9.]')" != "" ];then
        exit 1
    fi

     check_str=$(cat "$state"|grep -o "Feedback")

     if [ "$check_str" != "" ];then
         echo "${proxy_host}{proxy_port}\$$response_time"
     fi

      if [ -f $state ];then
          rm $state
      fi
     exit 0
}

#
# main routine
#
list="$HOME/.proxylist"

if [ -f "$list" ];then
     n=$(cat "$list"|wc -l)

     if (($n<5));then
         exit 1
     fi
else
     exit 1
fi

max_conn=10
begin=1
end=$(($max_conn-1))

if [ -f /tmp/proxies ];then
     rm /tmp/proxies
fi

while [ $begin -le $n ];do
     for ps in $(sed -n "$begin,$end p" ${list});do
         proxy_host=$(echo $ps|cut -d : -f 1)
         proxy_port=$(echo $ps|cut -d : -f 2)

         (check $proxy_host $proxy_port>>/tmp/proxies)&
     done
     
     # wait for something done   
     wait
     
     # next loop
     begin=$(($end+1))   
     if (( $end > $n ));then
         end=$n
     else
         end=$(($end+$max_conn-1))
     fi
done

# sort proxies by response_time
cat /tmp/proxies|sort -t \$ -k 2 -n>$HOME/.proxies
rm /tmp/proxies

exit 0[/PHP]
发表于 2005-11-19 12:20:08 | 显示全部楼层
哇,赞一个
一直想自己写一个的,这下好了,直接拿来用就可以了
回复 支持 反对

使用道具 举报

发表于 2005-11-21 23:20:39 | 显示全部楼层
非常好!
回复 支持 反对

使用道具 举报

发表于 2006-2-25 11:23:44 | 显示全部楼层

w3m是什么东西?

运行getproxy的过程中,出现了下面错误,请问是什么原因呢?
[PHP]
cat: /root/.post.data: 没有那个文件或目录
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  3 38623    3  1226    0     0   8686      0  0:00:04 --:--:--  0:00:04  8686  % Total    % Received % Xferd  Average Speed   Time    Time  Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 38623  100 38623    0     0   121k      0 --:--:-- --:--:-- --:--:--  217k
./getproxy .sh: line 35: w3m: command not found
100 17342  100 17342    0     0  45311      0 --:--:-- --:--:-- --:--:-- 90391
./getproxy .sh: line 35: w3m: command not found
[/PHP]
另外,post.data的文件是怎么下载下来的?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-2-25 11:59:36 | 显示全部楼层
Post by kentan
运行getproxy的过程中,出现了下面错误,请问是什么原因呢?
[PHP]
cat: /root/.post.data: 没有那个文件或目录
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  3 38623    3  1226    0     0   8686      0  0:00:04 --:--:--  0:00:04  8686  % Total    % Received % Xferd  Average Speed   Time    Time  Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 38623  100 38623    0     0   121k      0 --:--:-- --:--:-- --:--:--  217k
./getproxy .sh: line 35: w3m: command not found
100 17342  100 17342    0     0  45311      0 --:--:-- --:--:-- --:--:-- 90391
./getproxy .sh: line 35: w3m: command not found
[/PHP]
另外,post.data的文件是怎么下载下来的?

w3m 是一个字符界面下的WWW浏览器,我用它来将下载的html文件转为txt文本。

.post.data是从西交共享下载代理时需要的post数据。你可以用firefox配合livehttpheader插件来获取这些数据。
以前写的那个脚本有点问题,下面是修正后的版本。
getproxy.sh --  用来下载代理
checkproxy.sh -- 用来验证下载后的代理
.post.data  
xyzproxy.xpi   -- 可自动加载代理的xyzproxy版本

在crontab中使用的例子:
0,20,40 * * * * $HOME/bin/checkproxy.sh
40 */4 * * *    $HOME/bin/getproxy.sh

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表