云代理 · 专业版

接入指南

云代理服务器

地址:proxy.abuyun.com,端口:9010

代理隧道通过用户名/密码的形式进行身份认证,该认证信息最终会转换为『Proxy-Authorization』协议头跟随请求一起发出。

为便于部分语言进行接入,平台亦支持通过『Authorization』协议头进行隧道身份验证。

代理服务接入步骤如下:

  1. 在阿布云注册账号后,去服务管理控制台的 “HTTP代理” 页中选购代理产品。

  2. 完成支付后,在服务管理控制台的 “HTTP代理” 页中会看到已经购买到的专业版代理隧道列表。

  3. 每一条隧道都有自己的 “通行证书” 及 “通行密钥”,分别对应代理验证授权的 “用户名” 及 “密码”。

  4. 如果是通过浏览器使用代理隧道,请设置浏览器代理的服务器地址及端口。设置并保存配置后,在浏览器中打开任意网址,会弹出一个授权验证窗口,输入代理隧道的 “通行证书” 及 “通行密钥” 后,确认即可。

    示例配置如下:

    火狐浏览器以使用 AutoProxy 插件为例,在 AutoProxy 的“代理服务器”配置中增加名为“abuyun”的配置:

    新增完成之后,切换使用“abuyun”代理。

    在地址栏中输入任意网址,会弹出如下提示框:

    输入对应的“通行证书” 及 “通行密钥”后,即可完成配置。之后在该浏览器打开的页面都会通过阿布云代理请求。

    谷歌浏览器以使用 SwitchyOmega 为例,去谷歌应用商店或 GitHub 下载安装完 SwitchyOmega 后。在 SwitchyOmega 的设置界面中新建名为“abuyun”的情景模式:

    情景模式创建好之后,配置该模式的代理服务器。

    然后,点击右侧的小锁图标设置登录信息,输入对应的“通行证书” 及 “通行密钥”即可。

    情景模式设置完成后,切换至“abuyun”情景模式。

    之后在该浏览器打开的页面都会通过阿布云代理请求。

    以参数方式传递代理信息,示例如下:

    phantomjs --proxy=http://proxy.abuyun.com:9010 --proxy-auth=H01234567890123P:0123456789012345 --ignore-ssl-errors=true http-demo.js

    http-demo.js 内容如下:

                                                    
        var page = require('webpage').create();
    
        page.onResourceReceived = function(j) {
          for (var i = 0; i < j.headers.length; ++i) {
            console.log(j.headers[i].name + ': ' + j.headers[i].value);
          }
        };
    
        page.open("http://test.abuyun.com/proxy.php", {}, function(status) {
          console.log('status> ' + status);
    
          setTimeout(function() {
            phantom.exit();
          }, 3000);
        });
                                                    
                                                
                                                    
        curl -v -x "http://proxy.abuyun.com:9010" --proxy-basic --proxy-user H01234567890123P:0123456789012345 http://ip.cn
    
        // 切换隧道IP
        curl -x "http://proxy.abuyun.com:9010" --proxy-basic --proxy-user H01234567890123P:0123456789012345 http://proxy.abuyun.com/switch-ip
    
        // 查看隧道当前IP
        curl -x "http://proxy.abuyun.com:9010" --proxy-basic --proxy-user H01234567890123P:0123456789012345 http://proxy.abuyun.com/current-ip
                                                    
                                                
                                                    
        http --proxy=http://proxy.abuyun.com:9010 --auth-type=basic --auth=H01234567890123P:0123456789012345 http://ip.cn
    
        // 切换隧道IP
        http --proxy=http://proxy.abuyun.com:9010 --auth-type=basic --auth=H01234567890123P:0123456789012345 http://proxy.abuyun.com/switch-ip
    
        // 查看隧道当前IP
        http --proxy=http://proxy.abuyun.com:9010 --auth-type=basic --auth=H01234567890123P:0123456789012345 http://proxy.abuyun.com/current-ip
                                                    
                                                
  5. 在代码中使用代理隧道时,如果代码的 HTTP 请求方法不支持以用户名/密码的形式设置身份认证信息,则需要手动为每个 HTTP 请求增加『Proxy-Authorization』协议头,其值为 『Basic <base64>』。其中 『<base64>』 为 “通行证书” 和 “通行密钥” 通过 『:』 拼接后,再经由 BASE64 编码得到的字符串。

    正确设置后,发出的请求都将包含如下格式的 HTTP 协议头信息:

    Proxy-Authorization: Basic SDAxMjM0NTY3ODkwMTIzNDowMTIzNDU2Nzg5MDEyMzQ1

    云代理使用示例完整代码请移驾 GitHub » 如发现代码有不足或错误之处,欢迎提交 pull

    示例代码如下:

                                                            
        const http = require("http");
        const url  = require("url");
    
        // 要访问的目标页面
        const targetUrl = "http://test.abuyun.com/proxy.php";
        //const targetUrl = "http://proxy.abuyun.com/switch-ip";
        //const targetUrl = "http://proxy.abuyun.com/current-ip";
    
        const urlParsed   = url.parse(targetUrl);
    
        // 代理服务器
        const proxyHost = "proxy.abuyun.com";
        const proxyPort = "9010";
    
        // 代理隧道验证信息
        const proxyUser = "H01234567890123P";
        const proxyPass = "0123456789012345";
    
        const base64    = new Buffer(proxyUser + ":" + proxyPass).toString("base64");
    
        const options = {
            host    : proxyHost,
            port    : proxyPort,
            path    : targetUrl,
            method  : "GET",
            headers : {
                "Host"                : urlParsed.hostname,
                "Proxy-Authorization" : "Basic " + base64
            }
        };
    
        http
            .request(options, function(res) {
                console.log("got response: " + res.statusCode);
            })
            .on("error", function(err) {
                console.log(err);
            })
            .end()
        ;
                                                            
                                                        
                                                            
        const request = require("request");
    
        // 要访问的目标页面
        const targetUrl = "http://test.abuyun.com/proxy.php";
        //const targetUrl = "http://proxy.abuyun.com/switch-ip";
        //const targetUrl = "http://proxy.abuyun.com/current-ip";
    
        // 代理服务器
        const proxyHost = "proxy.abuyun.com";
        const proxyPort = 9010;
    
        // 代理隧道验证信息
        const proxyUser = "H01234567890123P";
        const proxyPass = "0123456789012345";
    
        const proxyUrl = "http://" + proxyUser + ":" + proxyPass + "@" + proxyHost + ":" + proxyPort;
    
        const proxiedRequest = request.defaults({'proxy': proxyUrl});
    
        const options = {
          url     : targetUrl,
          headers : {
            "Proxy-Switch-Ip" : "yes"
          }
        };
    
        proxiedRequest
            .get(options, function (err, res, body) {
                console.log("got response: " + res.statusCode);
            })
            .on("error", function (err) {
                console.log(err);
            })
        ;
                                                            
                                                        
                                                            
        const request = require("superagent");
    
        require("superagent-proxy")(request);
    
        // 要访问的目标页面
        const targetUrl = "http://test.abuyun.com/proxy.php";
        //const targetUrl = "http://proxy.abuyun.com/switch-ip";
        //const targetUrl = "http://proxy.abuyun.com/current-ip";
    
        // 代理服务器
        const proxyHost = "proxy.abuyun.com";
        const proxyPort = 9010;
    
        // 代理隧道验证信息
        const proxyUser = "H01234567890123P";
        const proxyPass = "0123456789012345";
    
        const proxyUrl = "http://" + proxyUser + ":" + proxyPass + "@" + proxyHost + ":" + proxyPort;
    
        request
            .get(targetUrl)
            .proxy(proxyUrl)
            .end(function onResponse(err, res) {
                if (err) {
                    return console.log(err);
                }
    
                console.log(res.status, res.headers);
                console.log(res.text);
            })
        ;
                                                            
                                                        
                                                    
        // 要访问的目标页面
        $targetUrl = "http://test.abuyun.com/proxy.php";
        //$targetUrl = "http://proxy.abuyun.com/switch-ip";
        //$targetUrl = "http://proxy.abuyun.com/current-ip";
    
        // 代理服务器
        $proxyServer = "http://proxy.abuyun.com:9010";
    
        // 隧道身份信息
        $proxyUser   = "H01234567890123P";
        $proxyPass   = "0123456789012345";
    
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $targetUrl);
    
        curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
        // 设置代理服务器
        curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
        curl_setopt($ch, CURLOPT_PROXY, $proxyServer);
    
        // 设置隧道验证信息
        curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$proxyUser}:{$proxyPass}");
    
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727;)");
    
        //curl_setopt($ch, CURLOPT_HTTPHEADER, [
        //    "Proxy-Switch-Ip: yes",
        //]);
    
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
        $result = curl_exec($ch);
        //$info = curl_getinfo($ch);
    
        curl_close($ch);
    
        var_dump($result);
                                                    
                                                
                                                                
        # -*-*-
        # 感谢骚男 『苗伦兽 (QQ: 519714803)』 提供的源代码
        # -*-*-
    
        import java.io.ByteArrayOutputStream;
        import java.io.InputStream;
        import java.net.Authenticator;
        import java.net.HttpURLConnection;
        import java.net.InetSocketAddress;
        import java.net.PasswordAuthentication;
        import java.net.Proxy;
        import java.net.URL;
    
        class ProxyAuthenticator extends Authenticator {
            private String user, password;
    
            public ProxyAuthenticator(String user, String password) {
                this.user     = user;
                this.password = password;
            }
    
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, password.toCharArray());
            }
        }
    
        /**
         * 注意:下面代码仅仅实现HTTP请求链接,每一次请求都是无状态保留的,仅仅是这次请求是更换IP的,如果下次请求的IP地址会改变
         * 如果是多线程访问的话,只要将下面的代码嵌入到你自己的业务逻辑里面,那么每次都会用新的IP进行访问,如果担心IP有重复,
         * 自己可以维护IP的使用情况,并做校验。
         */
        public class ProxyTest {
            public static void main(String args[]) throws Exception {
                // 要访问的目标页面
                String targetUrl = "http://test.abuyun.com/proxy.php";
                //String targetUrl = "http://proxy.abuyun.com/switch-ip";
                //String targetUrl = "http://proxy.abuyun.com/current-ip";
    
                // 代理服务器
                String proxyServer = "proxy.abuyun.com";
                int proxyPort      = 9010;
    
                // 代理隧道验证信息
                String proxyUser  = "H01234567890123P";
                String proxyPass  = "0123456789012345";
    
                try {
                    URL url = new URL(targetUrl);
    
                    Authenticator.setDefault(new ProxyAuthenticator(proxyUser, proxyPass));
    
                    // 创建代理服务器地址对象
                    InetSocketAddress addr = new InetSocketAddress(proxyServer, proxyPort);
                    // 创建HTTP类型代理对象
                    Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
    
                    // 设置通过代理访问目标页面
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
                    // 设置IP切换头
                    connection.setRequestProperty("Proxy-Switch-Ip","yes");
    
                    // 解析返回数据
                    byte[] response = readStream(connection.getInputStream());
    
                    System.out.println(new String(response));
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }
            }
    
            /**
             * 将输入流转换成字符串
             *
             * @param inStream
             * @return
             * @throws Exception
             */
            public static byte[] readStream(InputStream inStream) throws Exception {
                ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len = -1;
    
                while ((len = inStream.read(buffer)) != -1) {
                    outSteam.write(buffer, 0, len);
                }
                outSteam.close();
                inStream.close();
    
                return outSteam.toByteArray();
            }
        }
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『不蛰不鸣 (QQ: 523-058-394)』 提供的源代码
        # -*-*-
    
        import java.io.IOException;
        import java.util.ArrayList;
        import java.util.List;
    
        import org.apache.http.Header;
        import org.apache.http.HttpHost;
        import org.apache.http.auth.AuthScope;
        import org.apache.http.auth.UsernamePasswordCredentials;
        import org.apache.http.client.AuthCache;
        import org.apache.http.client.CredentialsProvider;
        import org.apache.http.client.methods.CloseableHttpResponse;
        import org.apache.http.client.methods.HttpGet;
        import org.apache.http.client.protocol.HttpClientContext;
        import org.apache.http.impl.auth.BasicScheme;
        import org.apache.http.impl.client.BasicAuthCache;
        import org.apache.http.impl.client.BasicCredentialsProvider;
        import org.apache.http.impl.client.CloseableHttpClient;
        import org.apache.http.impl.client.HttpClients;
        import org.apache.http.message.BasicHeader;
        import org.apache.http.util.EntityUtils;
    
        public class JavaHttpClient45Demo
        {
            // 代理服务器
            final static String ProxyHost = "proxy.abuyun.com";
            final static Integer ProxyPort = 9010;
    
            // 代理隧道验证信息
            final static String ProxyUser = "H01234567890123P";
            final static String ProxyPass = "0123456789012345";
    
            // IP切换协议头
            final static String ProxyHeadKey = "Proxy-Switch-Ip";
            final static String ProxyHeadVal = "yes";
    
            public static void getUrlProxyContent(String url)
            {
                BasicHeader header = new BasicHeader(ProxyHeadKey, ProxyHeadVal);
                List<Header> list = new ArrayList<Header>();
                list.add(header);
    
                HttpHost target = new HttpHost(ProxyHost, ProxyPort, "http");
    
                CredentialsProvider credsProvider = new BasicCredentialsProvider();
                credsProvider.setCredentials(
                    new AuthScope(target.getHostName(), target.getPort()),
                    new UsernamePasswordCredentials(ProxyUser, ProxyPass));
    
                CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider)
                .setDefaultHeaders(list).build();
    
                // Create AuthCache instance
                AuthCache authCache = new BasicAuthCache();
                // Generate BASIC scheme object and add it to the local
                // auth cache
                BasicScheme basicAuth = new BasicScheme();
                authCache.put(target, basicAuth);
    
                // Add AuthCache to the execution context
                HttpClientContext localContext = HttpClientContext.create();
                localContext.setAuthCache(authCache);
    
                HttpGet httpGet = new HttpGet(url);
    
                CloseableHttpResponse response = null;
                try
                {
                    response = httpClient.execute(target, httpGet, localContext);
    
                    System.out.println(EntityUtils.toString(response.getEntity()));
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                finally
                {}
            }
    
            public static void main(String[] args)
            {
                // 要访问的目标页面
                String targetUrl = "https://test.abuyun.com/proxy.php";
                //String targetUrl = "http://proxy.abuyun.com/switch-ip";
                //String targetUrl = "http://proxy.abuyun.com/current-ip";
    
                getUrlProxyContent(targetUrl);
            }
        }
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『不蛰不鸣 (QQ: 523-058-394)』 提供的源代码
        # -*-*-
    
        import java.io.IOException;
        import java.net.Authenticator;
        import java.net.InetSocketAddress;
        import java.net.PasswordAuthentication;
        import java.net.Proxy;
    
        import org.jsoup.Jsoup;
        import org.jsoup.nodes.Document;
    
        /***
         * 通过阿布云代理访问指定URL 内容
         * 此处 Jsoup Version 1.9.1
         * @author sun
         */
        public class ProxyDemo
        {
            // 代理隧道验证信息
            final static String ProxyUser = "H01234567890123P";
            final static String ProxyPass = "0123456789012345";
    
            // 代理服务器
            final static String ProxyHost = "proxy.abuyun.com";
            final static Integer ProxyPort = 9010;
    
            // 设置IP切换头
            final static String ProxyHeadKey = "Proxy-Switch-Ip";
            final static String ProxyHeadVal = "yes";
    
            public static String getUrlProxyContent(String url)
            {
                Authenticator.setDefault(new Authenticator() {
                    public PasswordAuthentication getPasswordAuthentication()
                    {
                        return new PasswordAuthentication(ProxyUser, ProxyPass.toCharArray());
                    }
                });
    
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ProxyHost, ProxyPort));
    
                try
                {
                    // 此处自己处理异常、其他参数等
                    Document doc = Jsoup.connect(url).timeout(3000).header(ProxyHeadKey, ProxyHeadVal).proxy(proxy).get();
    
                    if(doc != null) {
                        System.out.println(doc.body().html());
                    }
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
    
                return null;
            }
    
            public static void main(String[] args) throws Exception
            {
                // 要访问的目标页面
                String targetUrl = "http://test.abuyun.com/proxy.php";
                //String targetUrl = "http://proxy.abuyun.com/switch-ip";
                //String targetUrl = "http://proxy.abuyun.com/current-ip";
    
                getUrlProxyContent(targetUrl);
            }
        }
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『黑白之间 (QQ: 420269696)』 提供的源代码
        # -*-*-
    
        import java.io.IOException;
        import java.nio.charset.Charset;
        import java.util.ArrayList;
        import java.util.HashMap;
        import java.util.List;
        import java.util.Map;
        import java.util.Set;
    
        import org.apache.commons.io.IOUtils;
        import org.apache.commons.lang.StringUtils;
        import org.apache.http.Header;
        import org.apache.http.HttpException;
        import org.apache.http.HttpHost;
        import org.apache.http.HttpRequest;
        import org.apache.http.HttpRequestInterceptor;
        import org.apache.http.HttpResponse;
        import org.apache.http.annotation.ThreadSafe;
        import org.apache.http.auth.AuthScope;
        import org.apache.http.auth.UsernamePasswordCredentials;
        import org.apache.http.client.AuthCache;
        import org.apache.http.client.CookieStore;
        import org.apache.http.client.CredentialsProvider;
        import org.apache.http.client.config.CookieSpecs;
        import org.apache.http.client.config.RequestConfig;
        import org.apache.http.client.methods.CloseableHttpResponse;
        import org.apache.http.client.methods.HttpGet;
        import org.apache.http.client.protocol.HttpClientContext;
        import org.apache.http.config.Registry;
        import org.apache.http.config.RegistryBuilder;
        import org.apache.http.config.SocketConfig;
        import org.apache.http.conn.socket.ConnectionSocketFactory;
        import org.apache.http.conn.socket.PlainConnectionSocketFactory;
        import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
        import org.apache.http.impl.auth.BasicScheme;
        import org.apache.http.impl.client.BasicAuthCache;
        import org.apache.http.impl.client.BasicCookieStore;
        import org.apache.http.impl.client.BasicCredentialsProvider;
        import org.apache.http.impl.client.CloseableHttpClient;
        import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
        import org.apache.http.impl.client.HttpClientBuilder;
        import org.apache.http.impl.client.HttpClients;
        import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
        import org.apache.http.impl.cookie.BasicClientCookie;
        import org.apache.http.message.BasicHeader;
        import org.apache.http.protocol.HttpContext;
        import org.apache.http.util.EntityUtils;
        import org.jsoup.Jsoup;
        import org.jsoup.nodes.Document;
        import org.jsoup.nodes.Element;
        import org.jsoup.select.Elements;
    
        import us.codecraft.webmagic.Page;
        import us.codecraft.webmagic.Request;
        import us.codecraft.webmagic.Site;
        import us.codecraft.webmagic.Spider;
        import us.codecraft.webmagic.Task;
        import us.codecraft.webmagic.downloader.Downloader;
        import us.codecraft.webmagic.processor.PageProcessor;
        import us.codecraft.webmagic.selector.PlainText;
        import us.codecraft.webmagic.utils.UrlUtils;
    
        /**
         * webmagic 0.5.3版本接入阿布云代理需要自定义下载组件,0.5.4版本作者代理池功能进行了改进并且加入了代理身份认证,推荐使用0.5.4版本,
         * 或许不用自定义下载组件
         */
        public class WebMagicProxyDemo
        {
            public static void main(String[] args) {
                Spider.create(new PageProcessor() {
                    @Override
                    public void process(Page page) {
                        System.out.println(page.getHtml());
                    }
    
                    @Override
                    public Site getSite() {
                        return Site.me();
                    }
                }).setDownloader(new MyDownloader()).addUrl("https://test.abuyun.com/proxy.php").thread(1).run();
            }
        }
    
        @ThreadSafe
        class MyDownloader implements Downloader
        {
            // 代理服务器
            final static String proxyHost = "proxy.abuyun.com";
            final static Integer proxyPort = 9010;
    
            private HttpClientGenerator httpClientGenerator = new HttpClientGenerator();
    
            private final Map<String, CloseableHttpClient> httpClients = new HashMap<String, CloseableHttpClient>();
    
            @Override
            public void setThread(int threadNum) {}
    
            @Override
            public Page download(Request request, Task task) {
                Site site = task.getSite();
                Set<Integer> acceptStatCode = site.getAcceptStatCode();
                String charset = site.getCharset();
                CloseableHttpResponse httpResponse = null;
                int statusCode = 0;
    
                try {
                    HttpHost target = new HttpHost(proxyHost, proxyPort, "http");
                    site.setHttpProxy(target);
                    request.putExtra(Request.PROXY, target);
    
                    HttpClientContext localContext = HttpClientContext.create();
                    AuthCache authCache = new BasicAuthCache();
                    BasicScheme basicAuth = new BasicScheme();
                    authCache.put(site.getHttpProxy(), basicAuth);
                    localContext.setAuthCache(authCache);
    
                    HttpGet httpGet = new HttpGet(request.getUrl());
                    RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
                            .setConnectionRequestTimeout(site.getTimeOut()).setSocketTimeout(site.getTimeOut())
                            .setConnectTimeout(site.getTimeOut()).setCookieSpec(CookieSpecs.IGNORE_COOKIES);
                    httpGet.setConfig(requestConfigBuilder.build());
    
                    httpResponse = getHttpClient(site).execute(target, httpGet, localContext);
    
                    statusCode = httpResponse.getStatusLine().getStatusCode();
                    request.putExtra(Request.STATUS_CODE, statusCode);
    
                    if (statusAccept(acceptStatCode, statusCode)) {
                        Page page = handleResponse(request, charset, httpResponse, task);
                        onSuccess(request);
                        return page;
                    } else {
                        return null;
                    }
                } catch (IOException e) {
                    if (site.getCycleRetryTimes() > 0) {
                        return addToCycleRetry(request, site);
                    }
                    onError(request);
                    return null;
                } finally {
                    request.putExtra(Request.STATUS_CODE, statusCode);
                    try {
                        if (httpResponse != null) {
                            EntityUtils.consume(httpResponse.getEntity());
                        }
                    }
                    catch (IOException e) {
                    }
                }
            }
    
            private CloseableHttpClient getHttpClient(Site site) {
                String domain = site.getDomain();
                CloseableHttpClient httpClient = httpClients.get(domain);
    
                if (httpClient == null) {
                    synchronized (this) {
                        httpClient = httpClients.get(domain);
                        if (httpClient == null) {
                            httpClient = httpClientGenerator.getClient(site);
                            httpClients.put(domain, httpClient);
                        }
                    }
                }
    
                return httpClient;
            }
    
            protected boolean statusAccept(Set<Integer> acceptStatCode, int statusCode) {
                return acceptStatCode.contains(statusCode);
            }
    
            protected Page handleResponse(Request request, String charset, HttpResponse httpResponse, Task task)
                    throws IOException {
                String content = getContent(charset, httpResponse);
    
                Page page = new Page();
                page.setRawText(content);
                page.setUrl(new PlainText(request.getUrl()));
                page.setRequest(request);
                page.setStatusCode(httpResponse.getStatusLine().getStatusCode());
    
                return page;
            }
    
            protected String getContent(String charset, HttpResponse httpResponse) throws IOException {
                if (charset == null) {
                    byte[] contentBytes = IOUtils.toByteArray(httpResponse.getEntity().getContent());
                    String htmlCharset = getHtmlCharset(httpResponse, contentBytes);
    
                    if (htmlCharset != null) {
                        return new String(contentBytes, htmlCharset);
                    } else {
                        return new String(contentBytes);
                    }
                } else {
                    return IOUtils.toString(httpResponse.getEntity().getContent(), charset);
                }
            }
    
            protected String getHtmlCharset(HttpResponse httpResponse, byte[] contentBytes) throws IOException {
                String charset = null;
                String value = httpResponse.getEntity().getContentType().getValue();
                charset = UrlUtils.getCharset(value);
                if (StringUtils.isNotBlank(charset)) {
                    return charset;
                }
    
                Charset defaultCharset = Charset.defaultCharset();
                String content = new String(contentBytes, defaultCharset.name());
                if (StringUtils.isNotEmpty(content)) {
                    Document document = Jsoup.parse(content);
                    Elements links = document.select("meta");
    
                    for (Element link : links) {
                        String metaContent = link.attr("content");
                        String metaCharset = link.attr("charset");
    
                        if (metaContent.indexOf("charset") != -1) {
                            metaContent = metaContent.substring(metaContent.indexOf("charset"), metaContent.length());
                            charset = metaContent.split("=")[1];
                            break;
                        } else if (StringUtils.isNotEmpty(metaCharset)) {
                            charset = metaCharset;
                            break;
                        }
                    }
                }
    
                return charset;
            }
    
            protected void onSuccess(Request request) {}
    
            protected void onError(Request request) {}
    
            protected Page addToCycleRetry(Request request, Site site) {
                Page page = new Page();
                Object cycleTriedTimesObject = request.getExtra(Request.CYCLE_TRIED_TIMES);
    
                if (cycleTriedTimesObject == null) {
                    page.addTargetRequest(request.setPriority(0).putExtra(Request.CYCLE_TRIED_TIMES, 1));
                } else {
                    int cycleTriedTimes = (Integer) cycleTriedTimesObject;
                    cycleTriedTimes++;
                    if (cycleTriedTimes >= site.getCycleRetryTimes()) {
                        return null;
                    }
                    page.addTargetRequest(request.setPriority(0).putExtra(Request.CYCLE_TRIED_TIMES, cycleTriedTimes));
                }
    
                page.setNeedCycleRetry(true);
    
                return page;
            }
        }
    
        class HttpClientGenerator
        {
            private PoolingHttpClientConnectionManager connectionManager;
    
            // 代理隧道验证信息
            final static String proxyUser = "H01234567890123P";
            final static String proxyPass = "0123456789012345";
    
            public HttpClientGenerator() {
                Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory> create()
                        .register("http", PlainConnectionSocketFactory.INSTANCE)
                        .register("https", SSLConnectionSocketFactory.getSocketFactory()).build();
                connectionManager = new PoolingHttpClientConnectionManager(reg);
                connectionManager.setDefaultMaxPerRoute(100);
            }
    
            public HttpClientGenerator setPoolSize(int poolSize) {
                connectionManager.setMaxTotal(poolSize);
                return this;
            }
    
            public CloseableHttpClient getClient(Site site) {
                return generateClient(site);
            }
    
            private CloseableHttpClient generateClient(Site site) {
                List<Header> list = new ArrayList<Header>();
                BasicHeader header = new BasicHeader("Proxy-Switch-Ip", "yes");
                list.add(header);
                if (site.getHeaders() != null) {
                    for (Map.Entry<String, String> headerEntry : site.getHeaders().entrySet()) {
                        list.add(new BasicHeader(headerEntry.getKey(), headerEntry.getValue()));
                    }
                }
    
                HttpHost target = site.getHttpProxy();
                CredentialsProvider credsProvider = new BasicCredentialsProvider();
                credsProvider.setCredentials(new AuthScope(target.getHostName(), target.getPort()),
                        new UsernamePasswordCredentials(proxyUser, proxyPass));
    
                HttpClientBuilder httpClientBuilder = HttpClients.custom().setConnectionManager(connectionManager)
                        .setDefaultCredentialsProvider(credsProvider).setDefaultHeaders(list);
    
                if (site != null && site.getUserAgent() != null) {
                    httpClientBuilder.setUserAgent(site.getUserAgent());
                } else {
                    httpClientBuilder.setUserAgent("");
                }
    
                if (site == null || site.isUseGzip()) {
                    httpClientBuilder.addInterceptorFirst(new HttpRequestInterceptor() {
                        public void process(final HttpRequest request, final HttpContext context)
                                throws HttpException, IOException {
                            if (!request.containsHeader("Accept-Encoding")) {
                                request.addHeader("Accept-Encoding", "gzip");
                            }
                        }
                    });
                }
    
                SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).build();
                httpClientBuilder.setDefaultSocketConfig(socketConfig);
    
                if (site != null) {
                    httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(site.getRetryTimes(), true));
                }
    
                generateCookie(httpClientBuilder, site);
    
                return httpClientBuilder.build();
            }
    
            private void generateCookie(HttpClientBuilder httpClientBuilder, Site site) {
                CookieStore cookieStore = new BasicCookieStore();
    
                for (Map.Entry<String, String> cookieEntry : site.getCookies().entrySet()) {
                    BasicClientCookie cookie = new BasicClientCookie(cookieEntry.getKey(), cookieEntry.getValue());
                    cookie.setDomain(site.getDomain());
                    cookieStore.addCookie(cookie);
                }
    
                for (Map.Entry<String, Map<String, String>> domainEntry : site.getAllCookies().entrySet()) {
                    for (Map.Entry<String, String> cookieEntry : domainEntry.getValue().entrySet()) {
                        BasicClientCookie cookie = new BasicClientCookie(cookieEntry.getKey(), cookieEntry.getValue());
                        cookie.setDomain(domainEntry.getKey());
                        cookieStore.addCookie(cookie);
                    }
                }
    
                httpClientBuilder.setDefaultCookieStore(cookieStore);
            }
        }
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『│網亊隨楓︵ (QQ: 332110637)』 提供的源代码
        # -*-*-
    
        #! -*- encoding:utf-8 -*-
    
        from urllib import request
    
        # 要访问的目标页面
        targetUrl = "http://test.abuyun.com/proxy.php"
        # targetUrl = "http://proxy.abuyun.com/switch-ip"
        # targetUrl = "http://proxy.abuyun.com/current-ip"
    
        # 代理服务器
        proxyHost = "proxy.abuyun.com"
        proxyPort = "9010"
    
        # 代理隧道验证信息
        proxyUser = "H01234567890123P"
        proxyPass = "0123456789012345"
    
        proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
            "host" : proxyHost,
            "port" : proxyPort,
            "user" : proxyUser,
            "pass" : proxyPass,
        }
    
        proxy_handler = request.ProxyHandler({
            "http"  : proxyMeta,
            "https" : proxyMeta,
        })
    
        #auth = request.HTTPBasicAuthHandler()
        #opener = request.build_opener(proxy_handler, auth, request.HTTPHandler)
    
        opener = request.build_opener(proxy_handler)
    
        # opener.addheaders = [("Proxy-Switch-Ip", "yes")]
        request.install_opener(opener)
        resp = request.urlopen(targetUrl).read()
    
        print (resp)
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『zh (QQ: 315393472)』 提供的源代码
        # -*-*-
    
        #! -*- encoding:utf-8 -*-
    
        import urllib2
    
        # 要访问的目标页面
        targetUrl = "http://test.abuyun.com/proxy.php"
        #targetUrl = "http://proxy.abuyun.com/switch-ip"
        #targetUrl = "http://proxy.abuyun.com/current-ip"
    
        # 代理服务器
        proxyHost = "proxy.abuyun.com"
        proxyPort = "9010"
    
        # 代理隧道验证信息
        proxyUser = "H01234567890123P"
        proxyPass = "0123456789012345"
    
        proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
          "host" : proxyHost,
          "port" : proxyPort,
          "user" : proxyUser,
          "pass" : proxyPass,
        }
    
        proxy_handler = urllib2.ProxyHandler({
            "http"  : proxyMeta,
            "https" : proxyMeta,
        })
    
        opener = urllib2.build_opener(proxy_handler)
    
        #opener.addheaders = [("Proxy-Switch-Ip", "yes")]
        urllib2.install_opener(opener)
        resp = urllib2.urlopen(targetUrl).read()
    
        print resp
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『zh (QQ: 315393472)』 提供的源代码
        # -*-*-
    
        #! -*- encoding:utf-8 -*-
    
        import requests
    
        # 要访问的目标页面
        targetUrl = "http://test.abuyun.com/proxy.php"
        #targetUrl = "http://proxy.abuyun.com/switch-ip"
        #targetUrl = "http://proxy.abuyun.com/current-ip"
    
        # 代理服务器
        proxyHost = "proxy.abuyun.com"
        proxyPort = "9010"
    
        # 代理隧道验证信息
        proxyUser = "H01234567890123P"
        proxyPass = "0123456789012345"
    
        proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
          "host" : proxyHost,
          "port" : proxyPort,
          "user" : proxyUser,
          "pass" : proxyPass,
        }
    
        proxies = {
            "http"  : proxyMeta,
            "https" : proxyMeta,
        }
    
        resp = requests.get(targetUrl, proxies=proxies)
    
        print resp.status_code
        print resp.text
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『挖掘机强森 (QQ: 615918332)』 指正
        # -*-*-
    
        #! -*- encoding:utf-8 -*-
    
        import base64
    
        # 代理服务器
        proxyServer = "http://proxy.abuyun.com:9010"
    
        # 代理隧道验证信息
        proxyUser = "H01234567890123P"
        proxyPass = "0123456789012345"
    
        proxyAuth = "Basic " + base64.b64encode(proxyUser + ":" + proxyPass)
    
        class ProxyMiddleware(object):
            def process_request(self, request, spider):
                request.meta["proxy"] = proxyServer
    
                request.headers["Proxy-Authorization"] = proxyAuth
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『专注爬虫二十年 (QQ: 601245227)』 提供的源代码
        # -*-*-
    
        import org.json.JSONException;
        import org.json.JSONObject;
        import org.openqa.selenium.Platform;
        import org.openqa.selenium.Proxy;
        import org.openqa.selenium.htmlunit.HtmlUnitDriver;
        import org.openqa.selenium.remote.CapabilityType;
        import org.openqa.selenium.remote.DesiredCapabilities;
    
        import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
        import com.gargoylesoftware.htmlunit.WebClient;
    
        public class HtmlUnitDriverProxyDemo
        {
            // 代理隧道验证信息
            final static String proxyUser = "H01234567890123P";
            final static String proxyPass = "0123456789012345";
    
            // 代理服务器
            final static String proxyServer = "proxy.abuyun.com:9010";
    
            public static void main(String[] args) throws JSONException
            {
                HtmlUnitDriver driver = getHtmlUnitDriver();
    
                driver.get("https://test.abuyun.com/test.php");
    
                String title = driver.getTitle();
                System.out.println(title);
            }
    
            public static HtmlUnitDriver getHtmlUnitDriver()
            {
                HtmlUnitDriver driver = null;
    
                Proxy proxy = new Proxy();
                // 设置代理服务器地址
                proxy.setHttpProxy(proxyServer);
    
                DesiredCapabilities capabilities = DesiredCapabilities.htmlUnit();
                capabilities.setCapability(CapabilityType.PROXY, proxy);
                capabilities.setJavascriptEnabled(true);
                capabilities.setPlatform(Platform.WIN8_1);
    
                driver = new HtmlUnitDriver(capabilities) {
                    @Override
                    protected WebClient modifyWebClient(WebClient client) {
                        DefaultCredentialsProvider creds = new DefaultCredentialsProvider();
                        creds.addCredentials(proxyUser, proxyPass);
                        client.setCredentialsProvider(creds);
                        return client;
                    }
                };
    
                driver.setJavascriptEnabled(true);
    
                return driver;
            }
        }
                                                                
                                                            
                                                                
        # -*-*-
        # 感谢骚男 『专注爬虫二十年 (QQ: 601245227)』 提供的源代码
        # -*-*-
    
        import org.json.JSONException;
        import org.json.JSONObject;
        import org.openqa.selenium.Platform;
        import org.openqa.selenium.Proxy;
        import org.openqa.selenium.firefox.FirefoxDriver;
        import org.openqa.selenium.firefox.FirefoxProfile;
        import org.openqa.selenium.htmlunit.HtmlUnitDriver;
        import org.openqa.selenium.remote.CapabilityType;
        import org.openqa.selenium.remote.DesiredCapabilities;
    
        import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
        import com.gargoylesoftware.htmlunit.WebClient;
    
        public class FirefoxDriverProxyDemo
        {
            // 代理隧道验证信息
            final static String proxyUser = "H01234567890123P";
            final static String proxyPass = "0123456789012345";
    
            // 代理服务器
            final static String proxyHost = "proxy.abuyun.com";
            final static int proxyPort = 9010;
    
            final static String firefoxBin = "D:/Program Files/Mozilla Firefox/firefox.exe";
    
            public static void main(String[] args) throws JSONException
            {
                System.setProperty("webdriver.firefox.bin", firefoxBin);
    
                FirefoxProfile profile = new FirefoxProfile();
                // 使用代理
                profile.setPreference("network.proxy.type", 1);
                // 代理服务器配置
                profile.setPreference("network.proxy.http", proxyHost);
                profile.setPreference("network.proxy.http_port", proxyPort);
    
                profile.setPreference("network.proxy.ssl", proxyHost);
                profile.setPreference("network.proxy.ssl_port", proxyPort);
    
                profile.setPreference("username", proxyUser);
                profile.setPreference("password", proxyPass);
    
                // 所有协议公用一种代理配置,如果单独配置,这项设置为false
                profile.setPreference("network.proxy.share_proxy_settings", true);
    
                // 对于localhost的不用代理,这里必须要配置,否则无法和webdriver通讯
                profile.setPreference("network.proxy.no_proxies_on", "localhost");
    
                // 以代理方式启动firefox
                FirefoxDriver driver = new FirefoxDriver(profile);
            }
        }
                                                                
                                                            
                                                    
        # -*-*-
        # 感谢骚男 『Jonathan (QQ: 1632126)』 提供的源代码
        # -*-*-
    
        package main
    
        import (
            "net/url"
            "net/http"
            "bytes"
            "fmt"
            "io/ioutil"
        )
    
        const ProxyServer = "proxy.abuyun.com:9010"
    
        type AbuyunProxy struct {
            AppID string
            AppSecret string
        }
    
        func (p AbuyunProxy) ProxyClient() http.Client {
            proxyURL, _ := url.Parse("http://"+p.AppID+":"+p.AppSecret+"@"+ProxyServer)
            return http.Client{Transport: &http.Transport{Proxy:http.ProxyURL(proxyURL)}}
        }
    
        func main()  {
            targetURI := "http://test.abuyun.com/proxy.php"
            //targetURI := "https://www.abuyun.com/switch-ip"
            //targetURI := "https://www.abuyun.com/current-ip"
    
            // 初始化 proxy http client
            client := AbuyunProxy{AppID: "your appid", AppSecret: "your appsecret"}.ProxyClient()
    
            request, _ := http.NewRequest("GET", targetURI, bytes.NewBuffer([]byte(``)))
    
            // 设置IP切换头 (只支持 HTTP)
            request.Header.Set("Proxy-Switch-Ip", "yes")
    
            response, err := client.Do(request)
    
            if err != nil {
                panic("failed to connect: " + err.Error())
            } else {
                bodyByte, err := ioutil.ReadAll(response.Body)
                if err != nil {
                    fmt.Println("读取 Body 时出错", err)
                    return
                }
                response.Body.Close()
    
                body := string(bodyByte)
    
                fmt.Println("Response Status:", response.Status)
                fmt.Println("Response Header:", response.Header)
                fmt.Println("Response Body:\n", body)
            }
        }
                                                    
                                                
                                                    
        # -*-*-
        # 感谢骚男 『黄戴森 (QQ: 805721078)』 提供的源代码
        # -*-*-
    
        interface
    
        uses
            Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
            Dialogs, StdCtrls, IDHTTP;
    
        type
            TForm1 = class(TForm)
                Button1: TButton;
                procedure Button1Click(Sender: TObject);
            private
                { Private declarations }
            public
                { Public declarations }
            end;
    
        var
            Form1: TForm1;
    
        implementation
    
        {$R *.dfm}
    
        procedure TForm1.Button1Click(Sender: TObject);
        const
            // 要访问的目标页面
            targetUrl  = 'http://test.abuyun.com/proxy.php';
            //targetUrl  = 'http://proxy.abuyun.com/switch-ip';
            //targetUrl = 'http://proxy.abuyun.com/current-ip';
    
            // 代理服务器
            proxyServer = 'proxy.abuyun.com';
            proxyPort = 9010;
    
            // 代理隧道验证信息
            proxyUser = 'H01234567890123P';
            proxyPass = '0123456789012345';
        var
            IDHTTP1 : TIDHTTP;
        begin
            Application.ProcessMessages;
            IDHTTP1 := TIDHTTP.Create(nil);
            with IDHTTP1 do
            begin
                AllowCookies := True;
                HandleRedirects := True;
                ProxyParams.BasicAuthentication := True;
                ProxyParams.ProxyServer := proxyServer;
                ProxyParams.ProxyPort := proxyPort;
                ProxyParams.ProxyUsername := proxyUser;
                ProxyParams.ProxyPassword := proxyPass;
                //Request.Method := 'GET';
                //Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
                //Request.AcceptEncoding := 'gzip, deflate, sdch';
                //Request.AcceptLanguage := 'zh-CN,zh;q=0.8';
                //Request.Connection := 'keep-alive';
                Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko)';
                IDHTTP1.Get(targetUrl);
            end;
        end;
    
        end.
                                                    
                                                
                                                    
        # -*-*-
        # 感谢骚男 『yvon (QQ: 917512804)』 提供的源代码
        # -*-*-
    
        // 要访问的目标页面
        string targetUrl = "http://test.abuyun.com/proxy.php";
        //string targetUrl = "http://proxy.abuyun.com/switch-ip";
        //string targetUrl = "http://proxy.abuyun.com/current-ip";
    
        // 代理服务器
        string proxyHost = "http://proxy.abuyun.com";
        string proxyPort = "9010";
    
        // 代理隧道验证信息
        string proxyUser = "H01234567890123P";
        string proxyPass = "0123456789012345";
    
        // 设置代理服务器
        var proxy         = new WebProxy();
        proxy.Address     = new Uri(string.Format("{0}:{1}", proxyHost, proxyPort));
        proxy.Credentials = new NetworkCredential(proxyUser, proxyPass);
    
        ServicePointManager.Expect100Continue = false;
    
        var request = WebRequest.Create(targetUrl) as HttpWebRequest;
    
        request.AllowAutoRedirect = true;
        request.KeepAlive = true;
        request.Method    = "GET";
        request.Proxy     = proxy;
    
        //request.Timeout = 20000;
        //request.ServicePoint.ConnectionLimit = 512;
        //request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36";
        //request.Headers.Add("Cache-Control", "max-age=0");
        //request.Headers.Add("DNT", "1");
    
        using (var response = request.GetResponse() as HttpWebResponse)
        using (var sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
        {
            string htmlStr = sr.ReadToEnd();
        }
                                                    
                                                
                                                    
        # -*-*-
        # 感谢骚男 『爱尔蓝橘子 (QQ: 84316577)』 提供的源代码
        # -*-*-
    
        HTTPREQUEST_PROXYSETTING_PROXY := 2
        HTTPREQUEST_SETCREDENTIALS_FOR_PROXY := 1
    
        ;~ 代理服务器
        proxyHost := "proxy.abuyun.com:9010"
    
        ;~ 代理隧道验证信息
        proxyUser := "H01234567890123P"
        proxyPass := "0123456789012345"
    
        ;~ 要访问的目标页面
        targetUrl := "http://test.abuyun.com/proxy.php"
    
        whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
        whr.Open("GET", targetUrl, true)
    
        ;~ 模拟curl的ua,方便测试
        whr.SetRequestHeader("User-Agent", "curl/7.41.0")
    
        ;~ 设置代理服务器
        whr.SetProxy(HTTPREQUEST_PROXYSETTING_PROXY, proxyHost)
    
        ;~ 设置代理隧道验证信息
        whr.SetCredentials(proxyUser, proxyPass, HTTPREQUEST_SETCREDENTIALS_FOR_PROXY)
    
        whr.Send()
        whr.WaitForResponse()
    
        MsgBox % whr.ResponseText
                                                    
                                                
                                                    
        # -*-*-
        # 感谢骚男 『起风了 (QQ: 873967724)』 提供的源代码
        # -*-*-
                                                    
                                                    点击下载
                                                

手动切换 IP 的方式有两种:

  1. 应用程序通过代理隧道请求 『http://proxy.abuyun.com/switch-ip』 后,请求执行成功会返回一个新的代理IP地址及其相关信息,阿布云会将当前代理隧道切换至该 IP。从下一个请求起,数据都会通过新的 IP 地址进行转发。
  2. 在 HTTP 请求中增加键为 『Proxy-Switch-Ip』, 值为 『yes』 的协议头信息,应用程序将请求通过代理隧道发出后,阿布云会立即为该隧道切换一个新的 IP,当前请求和随后发起的请求都会通过新的 IP 地址进行转发。

请求 『http://proxy.abuyun.com/current-ip』 可以获取隧道当前使用的代理IP信息。

http://proxy.abuyun.com/switch-ip』与『http://proxy.abuyun.com/current-ip』返回三个字段,各字段间用半角逗号分隔:

正在使用的 IP 地址』、『该 IP 已使用时长』、『该 IP 可继续使用时长

友情连接