产品说明

    隧道代理提供统一的入口地址,用户成功接入后,每一个请求都是一个随机 IP。

隧道验证方式

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

服务接入步骤

    在小象注册账号后,前往 “隧道代理” 页中选购隧道产品。
       完成支付后,在”后台-产品管理-隧道代理” 页中会看到已经购买到的相应版本HTTP隧道。
       每一条HTTP隧道都拥有独立的 “通行证书” 及 “通行密钥”,分别对应代理验证授权的 “app_id” 及 “密码”。
       通过浏览器使用HTTP隧道,请设置浏览器代理的服务器地址及端口。设置并保存配置后,在浏览器中打开任意网址,会弹出一个授权验证窗口,输入隧道的 “app_id” 及 “密码” 后,确认即可。
       在代码中使用HTTP隧道时,如果代码的 HTTP 请求方法不支持以用户名/密码的形式设置身份认证信息,则需要手动为每个 HTTP 请求增加『Proxy-Authorization』协议头,其值为 『Basic 』。其中『 』 为 “通行证书” 和 “通行密钥” 通过 『:』 拼接后,再经由 BASE64 编码得到的字符串。 正确设置后,发出的请求都将包含如下格式的 HTTP 协议头信息:

       Proxy-Authorization: Basic MTIzNDU2Nzg5MDEyMzQ1Njc4OmFiY2RlZmdo

IP手动切换方式

    在 HTTP 请求中增加键为『Proxy-Switch-Ip』, 值为『true』的协议头信息,应用程序将请求通过隧道发出后,HTTP隧道会立刻切换一个新的IP,当前请求和随后发起的请求都会通过新的 IP地址 进行转发。

隧道代理服务器地址

      隧道代理(短效版)代理服务器地址为:http-short.xiaoxiangdaili.com

      代理端口为:10010


      隧道代理(动态转发)代理服务器地址为:http-dynamic.xiaoxiangdaili.com

      代理端口为:10030

示例代码

  • Java
  • Python2
  • Python3
  • PHP
  • Golang
  • Node.js
  • C#
  • Scrapy
  • Curl
    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;


    public class ProxyDemo {
        // 代理隧道验证信息
        private final static String ProxyUser = "app_id(后台-产品管理-隧道代理页面可查)";
        private final static String ProxyPass = "密码(后台-产品管理-隧道代理页面可查)";

        // 代理服务器
        private final static String ProxyHost = "http-short.xiaoxiangdaili.com";
        private final static Integer ProxyPort = 10010;

        private static void getUrlProxyContent(String url) {
            Authenticator.setDefault(new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(ProxyUser, ProxyPass.toCharArray());
                }
            });

            System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ProxyHost, ProxyPort));

            try {
                Document doc = Jsoup.connect(url).timeout(3000).proxy(proxy).get();

                if (doc != null) {
                    System.out.println(doc.body().html());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) throws Exception {
            // 要访问的目标页面
            String targetUrl = http://api.ip.sb/ip;

            getUrlProxyContent(targetUrl);
        }
    }
                    

    import requests

    target_url = "http://api.ip.sb/ip"
    proxy_host = 'http-short.xiaoxiangdaili.com'
    proxy_port = 10010
    proxy_username = 'app_id(后台-产品管理-隧道代理页面可查)'
    proxy_pwd = "密码(后台-产品管理-隧道代理页面可查)"

    proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
        "host": proxy_host,
        "port": proxy_port,
        "user": proxy_username,
        "pass": proxy_pwd,
    }

    proxies = {
        'http': proxyMeta,
        'https': proxyMeta,
    }

    try:
        resp = requests.get(url=target_url, proxies=proxies)
        print(resp.text)
    except Exception as e:
       print e

                    

    from urllib import request

    # 要访问的目标页面
    targetUrl = "http://api.ip.sb/ip"

    # 代理服务器
    proxyHost = "http-short.xiaoxiangdaili.com"
    proxyPort = "10010"

    # 代理隧道验证信息
    proxyUser = "app_id(后台-产品管理-隧道代理页面可查)"
    proxyPass = "密码(后台-产品管理-隧道代理页面可查)"

    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,
    })

    opener = request.build_opener(proxy_handler)

    request.install_opener(opener)
    resp = request.urlopen(targetUrl).read()

    print(resp)

                    

    <?php
    // 要访问的目标页面
    $targetUrl = "https://api.ip.sb/ip";

    // 代理服务器
    $proxyServer = "http://http-short.xiaoxiangdaili.com:10010";

    // 隧道身份信息
    // 这里的用户名,等于订单号
    $proxyUser = "app_id(后台-产品管理-隧道代理页面可查)";
    $proxyPass = "密码(后台-产品管理-隧道代理页面可查)";

    $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_CONNECTTIMEOUT, 3);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);

    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $result = curl_exec($ch);

    curl_close($ch);

    var_dump($result);


                    

    package main

    import (
        "github.com/parnurzeal/gorequest"
        "log"
        "fmt"
    )

    func main() {
        // TODO: 请替换下面的身份信息
        // 这里的用户名是隧道代理的订单号
        username := "app_id(后台-产品管理-隧道代理页面可查)"
        // 密码请到用户中心-我的订单页面查询
        password := "密码(后台-产品管理-隧道代理页面可查)"

        request := gorequest.New().
            Proxy(fmt.Sprintf("http://%s:%s@http-short.xiaoxiangdaili.com:10010", username, password))

        resp, body, errs := request.
            Get("http://api.ip.sb/ip").
            End()

        if errs != nil {
            log.Printf("出现异常:%s\n", errs)
            return
        }

        log.Printf("状态码:%d\n", resp.StatusCode)
        log.Printf("返回结果:%s\n", body)
    }

                    

    // 需要安装 request 库
    // 使用命令:npm install request
    // 仓库地址:https://github.com/request/request
    const request = require('request');

    var user = "app_id(后台-产品管理-隧道代理页面可查)"
    var password = "密码(后台-产品管理-隧道代理页面可查)"
    var host = "http-short.xiaoxiangdaili.com"
    var port = 10010

    var proxyUrl = "http://" + user + ":" + password + "@" + host + ":" + port;
    var proxiedRequest = request.defaults({'proxy': proxyUrl});

    proxiedRequest.get("http://api.ip.sb/ip", function (error, response, body) {
        console.log('error:', error);
        console.log('statusCode:', response && response.statusCode);
        console.log('body:', body);
    })

                    

    // 要访问的目标页面
    string targetUrl = "http://api.ip.sb/ip";

    // 代理服务器
    string proxyHost = "http://http-short.xiaoxiangdaili.com";
    string proxyPort = "10010";

    // 代理隧道验证信息
    string proxyUser = "app_id(后台-产品管理-隧道代理页面可查)";
    string proxyPass = "密码(后台-产品管理-隧道代理页面可查)";

    // 设置代理服务器
    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;


    using (var response = request.GetResponse() as HttpWebResponse)
    using (var sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
    {
        string htmlStr = sr.ReadToEnd();
    }

                    

    import scrapy
    import os

    class MyIPSpider(scrapy.Spider):
        name = 'my_ip'

        start_urls = [
            'https://api.ip.sb/ip?v=1',
            'https://api.ip.sb/ip?v=2',
        ]

        def start_requests(self):
            proxyUser = "app_id(后台-产品管理-隧道代理页面可查)"
            proxyPass = "密码(用户中心-隧道代理订单页面可查)"
            proxyHost = "http-short.xiaoxiangdaili.com"
            proxyPort = "10010"

            proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
                "host": proxyHost,
                "port": proxyPort,
                "user": proxyUser,
                "pass": proxyPass,
            }

            for url in self.start_urls:
                req = scrapy.Request(url, meta={'proxy': proxyMeta})
                yield req


        def parse(self, response):
            yield {
                'body': response.text,
            }

                    

    curl --proxy-header "Proxy-Authorization: Basic MTIzNDU2Nzg5MDEyMzQ1Njc4OmFiY2RlZmdo="  --proxy http://http-short.xiaoxiangdaili.com:10010 http://api.ip.sb/ip

                    

注意

  1. Java8以上版本,请在运行的时候,加上-Djdk.http.auth.tunneling.disabledSchemes=""。具体原因请参考:Unable to tunnel through proxy since Java 8 Update 111
  2. 使用 Python2 的示例代码访问 HTTPS 协议的 URL 会有问题,建议使用 Python3。

常见错误码

错误码 提示信息 说明
407 No Proxy-Authorization or Authorization can be found 请设置请求头Proxy-Authorization或者Authorization
407 Appkey is not a number appkey必须是数字
407 Not found 应用不存在
407 Disabled 应用已被禁用
407 Expired 应用已过期
407 Not found or expired 应用不存在或已过期
407 Wrong password 密码错误
407 Proxy type mismatch 产品类型不匹配
429 Too Many Requests 超过并发限制,请降低频率或者使用调整隧道代理套餐
500 Unknown exception 未知异常