zoukankan      html  css  js  c++  java
  • 物流一站式查询之TrackingMore篇

    连载篇提前看

    物流一站式查询之TrackingMore篇

    物流一站式查询之顺丰接口篇

    物流一站式查询之快递100篇

    快递查询接口

    目前提供快递查询的接口平台有:

    不同接口的区别:

    (1)Trackingmore支持380家快递公司,其中有55家为国内的快递,其余325家为国际快递。具体的价格为0.6分钱/单号左右,新注册用户可以免费测试12小时。

    (2)快递100属于在国内做得比较早的平台,可以申请每天最多2000次的API调用,但需要给快递100做一个友链。超过2000次收费,每次0.06~0.1元不等。

    (3)快递网可以申请每天最多500次的API调用,但同样需要做一个友链。超过部分,每次0.05元。

    快递API的应用场景与用途

    1. 最常见的应用场景如下:

    (1)电商网站:例如B2C、团购、B2B、批发分销站、C2C、本地生活交易等网站。

    (2)管理系统:订单处理平台、订货平台、发货平台、分销系统、渠道管理系统、客户管理系统、ERP等。

    2. 快递API的用途如下:

    (1)让顾客登录网站后,直接在“我的订单”页面内就能看到订单的物流状态。

    (2)自动筛选出“已签收”、“疑难件”等状态的单号,减轻物流跟单人员的压力。

    (3)改变订单的状态和交易流程,例如单号变为“已签收”,就能让订单变为可以确认退换货等。

    (4)评估选择快递公司,根据“已签收”的运单数,可以算出销售人员的业绩,且便于应对货到付款的结算。

    (5)邮件、短信提醒用户运单的最新状态,可以安抚用户,也可以利用邮件短信二次营销。

    对接示例

    这里以Trackingmore为例,不同的接口的对接方式比较类似,都需要注册,并生成自己的API key。以下以Trackingmore的实时查询API为例。

      接口支持的消息接收方式为HTTP POST

      请求方法的编码格式为 utf-8

      请求body部分的参数的数据格式为json 格式

    接口参数      

    接口请求地址

    http://api.trackingmore.com/v2/trackings/realtime

    请求头部信息参数

    参数名称 类型 说明 是否必须
    Content-Type: 
    application/json
    定义请求头部的数据格式
    Trackingmore-Api-Key: 
    string Trackingmore 后台获取的API

     请求body参数说明

    参数说明 类型 说明 是否必须
    tracking_number
    string 查询快递的快递单号
    carrier_code
    string trackingmore定义的快递商简码,比如china ems 就是china-ema

    carrier_code 参数是trackingmore 自己定义的快递商家的简码,具体的可以在这里查看

    还有需要注意的就是body部分这两个参数需要时json数据格式。大概样子就是这样的

    1 {
    2     "tracking_number": "LK664578623CN",
    3     "carrier_code": "china-ems"
    4 }

    返回参数定义

    参数名称 参数类型 参数说明 是否一定要返回该项值
    code
    数字 返回码 成功返回200,失败有其他队列的错误码
    type string 接口类型 成功返回Success
    message string 返回信息说明 成功返回Succes,失败返回队列的错误信息
    data json 查询到的物流信息 成功返回物流信息,失败返回空

    其他的状态响应简码可以在这里看到。

    这里把Trackingmore平台状态响应简码简单封装了下,代码如下:

      /// <summary>
        /// 典型的服务器响应 状态枚举
        /// </summary>
        public enum TrackMoreServerResponse
        {
            [Display(Name = "请求已成功 (一些 API 调用可能会相反返回 201)")]
            OK = 200,
    
            [Display(Name = "请求成功,已创建了资源")]
            Created = 201,
    
            [Display(Name = "请求已成功,但超过了数量限制")]
            CreatedFail = 202,
    
            [Display(Name = "身份验证失败或用户没有所请求的操作的权限")]
            Unauthorized = 401,
    
            [Display(Name = "无效的 API 密钥。请确保自己的申请API key的账户与调用API的服务器同时在国内或国外。即如果你的服务器在国外,你需要翻墙登录trackingmore网站进而获取API key")]
            UnauthorizedAPIInvalid = 4001,
    
            [Display(Name = "API 密钥已被删除")]
            UnauthorizedAPIDelete = 4002,
    
            [Display(Name = "请求不能理解或缺少必需的参数")]
            BadRequest = 4012,
    
            [Display(Name = "Tracking_number 是必需的")]
            BadRequest1 = 4013,
    
            [Display(Name = "Tracking_number 的值是无效的")]
            BadRequestInvalid = 4014,
    
            [Display(Name = "Carrier_code的值是无效的")]
            BadRequest3 = 4015,
    
    
            [Display(Name = "跟踪已存在")]
            BadRequest4 = 4016,
    
            [Display(Name = "跟踪并不存在")]
            BadRequest5 = 4017,
    
            [Display(Name = "由于过载风险此功能需要自定义激活。与 service@trackingmore.org 联系更多的信息。")]
            BadRequest6 = 4018,
    
    
            [Display(Name = "数量限制一次 200")]
            BadRequest7 = 4020,
    
            [Display(Name = "你的余额不够,所以你不能调用API请求数据")]
            BadRequest8 = 4021,
    
            [Display(Name = "请求已成功,但响应为空")]
            BadRequest9 = 4031,
    
            [Display(Name = "无法检测到快递")]
            NoContent = 4032,
    
            [Display(Name = "付款要求")]
            PaymentRequired = 402,
    
            [Display(Name = "访问被拒绝")]
            Forbidden = 403,
    
    
            [Display(Name = "找不到资源")]
            NotFound = 404,
    
            [Display(Name = "指定的资源不支持请求的方法")]
            MethodNotAllowed = 405,
    
            [Display(Name = "由于冲突,无法完成请求")]
            Conflict = 409,
    
            [Display(Name = "超过 API 限制。请求暂停,等待两分钟,然后再试")]
            TooManyRequests = 429,
    
            [Display(Name = "内部异常")]
            ServerError = 500,
    
            [Display(Name = "服务是临时不可用 (例如预定的平台维护)稍后再试")]
            ServiceUnavailable = 503,
    
        }
    View Code

    然后我们可以获取枚举描述值来快速知道返回了什么状态,而不用去官网查状态码的意思。这里也把获取枚举描述值的代码贴出来如下:

      /// <summary>
        /// 枚举辅助类
        /// </summary>
        public static class EnmHelper
        {
            /// <summary>
            /// 获取枚举值的描述
            /// </summary>
            /// <param name="sourceValue"></param>
            /// <returns></returns>
            public static string GetEnmName(this Enum sourceValue)
            {
                DisplayAttribute[] attributes = null;
                if (sourceValue != null)
                {
                    FieldInfo field = sourceValue.GetType().GetField(sourceValue.ToString());
                    if (field != null)
                    {
                        attributes =field .GetCustomAttributes(typeof(DisplayAttribute), false) as DisplayAttribute[];
                    }                
                }
                if (attributes==null|| attributes.Length < 1) return sourceValue.ToString();
                return attributes[0].Name;
            }
    
            /// <summary>
            /// 获取枚举集合列表
            /// </summary>
            /// <param name="enmType"></param>
            /// <returns></returns>
            public static List<ModItem> GetEnmList(this Type enmType)
            {
                List<EnmItem> result = new List<EnmItem>();
                Array array=  Enum.GetValues(enmType);
                foreach (var item in array)
                {
                    DisplayAttribute[] attributes = (DisplayAttribute[])item.GetType().GetField(item.ToString()).GetCustomAttributes(typeof(DisplayAttribute), false);
                    EnmItem enmItem = new EnmItem();
                    if (attributes.Length > 0)
                    {
                        enmItem.Name = attributes[0].Name;
                        enmItem.Value = Convert.ToInt32(item).ToString();
                        enmItem.OrderIndex = attributes[0].GetOrder().GetValueOrDefault(0);
                        result.Add(enmItem);
                    }
                }
                return result.OrderBy(x=>x.OrderIndex).Select(x=>x as ModItem).ToList();
            }
    
            /// <summary>
            /// 把字符串转换为枚举
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="source"></param>
            /// <returns></returns>
            public static T ConvertToEnm<T>(this string source)
            {
                return (T) ConvertToEnm(source,typeof(T));
            }
    
            /// <summary>
            /// 把字符串转换为枚举
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="source"></param>
            /// <returns></returns>
            public static object ConvertToEnm(this string source,Type enmType)
            {
                ModItem mod = enmType.GetEnmList().FirstOrDefault(x => x.Name == source);
                if (mod != null)
                {
                    source = mod.Value;
                }
                return Enum.Parse(enmType, source);
            }  
        }
    
        class EnmItem:ModItem
        {
           public  int OrderIndex { set; get; }
        }
    View Code

    一个枚举帮助类,其中ModItem类是自定义的一个类,里面就两个属性,Name、Value。

       public class ModItem
        {
            public string Name { set; get; }
    
            public string Value { set; get; }
        }

    像一般的调用接口获取物流信息,官网也有提供调用示例,点我去看示例

    完整的物流订阅、查询状态有更新触发回调url 示例

    现在假设你已经在More平台注册过,并生成创建了一个API Key。

    订阅篇

    ①创建一个接口的访问类(此类官方已提供)

     /// <summary>
        /// TrackingMore 每次发送必须带有Key 否则请求无效
        /// </summary>
        public class TrackingMoreAPI
        {
            private string ApiKey = ConfigHelper.GetKey("APIKey");
            public string getOrderTracesByJson(string requestData, string urlStr, string method)
            {
                string result = null;
                if (method.Equals("post"))
                {
                    string ReqURL = "http://api.trackingmore.com/v2/trackings/post";
                    string RelUrl = ReqURL + urlStr;
                    result = sendPost(ReqURL, requestData, "POST");
                }
                else if (method.Equals("get"))
                {
                    string ReqURL = "http://api.trackingmore.com/v2/trackings/get";
                    string RelUrl = ReqURL + urlStr;
                    //Console.WriteLine("RelUrl:" + RelUrl);
                    result = sendPost(RelUrl, requestData, "GET");
                }
                else if (method.Equals("batch"))
                {
                    string ReqURL = "http://api.trackingmore.com/v2/trackings/batch";
                    string RelUrl = ReqURL + urlStr;
                    //Console.WriteLine("RelUrl:" + RelUrl);
                    result = sendPost(RelUrl, requestData, "POST");
                }
                else if (method.Equals("codeNumberGet"))
                {
    
                    string ReqURL = "http://api.trackingmore.com/v2/trackings";
                    string RelUrl = ReqURL + urlStr;
                    //Console.WriteLine("RelUrl:" + RelUrl);
                    result = sendPost(RelUrl, requestData, "GET");
                }
                else if (method.Equals("codeNumberPut"))
                {
    
                    string ReqURL = "http://api.trackingmore.com/v2/trackings";
                    string RelUrl = ReqURL + urlStr;
                    //Console.WriteLine("RelUrl:" + RelUrl);
                    result = sendPost(RelUrl, requestData, "PUT");
                }
                else if (method.Equals("codeNumberDel"))
                {
    
                    string ReqURL = "http://api.trackingmore.com/v2/trackings";
                    string RelUrl = ReqURL + urlStr;
                    //Console.WriteLine("RelUrl:" + RelUrl);
                    result = sendPost(RelUrl, requestData, "DELETE");
                }
    
                else if (method.Equals("realtime"))
                {
    
                    string ReqURL = "http://api.trackingmore.com/v2/trackings/realtime";
                    string RelUrl = ReqURL + urlStr;
                    //Console.WriteLine("RelUrl:" + RelUrl);
                    result = sendPost(RelUrl, requestData, "POST");
                }
    
                return result;
            }
            private string sendPost(string url, string requestData, string method)
            {
                string result = "";
                byte[] byteData = null;
                if (requestData != null)
                {
                    byteData = Encoding.GetEncoding("UTF-8").GetBytes(requestData.ToString());
                }
                try
                {
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.Timeout = 30 * 1000;
                    request.Method = method;
                    request.Headers["Trackingmore-Api-Key"] = ApiKey;
    
                    if (byteData != null)
                    {
                        Stream stream = request.GetRequestStream();
                        stream.Write(byteData, 0, byteData.Length);
                        stream.Flush();
                        stream.Close();
                    }
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream backStream = response.GetResponseStream();
                    StreamReader sr = new StreamReader(backStream, Encoding.GetEncoding("UTF-8"));
                    result = sr.ReadToEnd();
                    sr.Close();
                    backStream.Close();
                    response.Close();
                    request.Abort();
                }
                catch (Exception ex)
                {
                    result = ex.Message;
                }
                return result;
            }
        }
    View Code

    ②创建一个TrackMoreModel模型类用于传输快递单号和快递公司编码

     public class TrackMoreModel
        {
            /// <summary>
            /// 快递单号
            /// </summary>
            public string tracking_number { get; set; }
            /// <summary>
            /// 快递公司编码
            /// </summary>
            public string carrier_code { get; set; }
    
        }
    View Code

    ③创建一个TrackMore快递信息跟踪类,里面可以包含你需要的一些访问接口的方法,如:创建快递单项目,查询单个物流信息、创建多个物流项目,查询多个物流信息、实时查询物流信息等。这里以创建单个快递单项目为例

    /// <summary>
        /// 快递跟踪信息
        /// </summary>
        public class TrackMore
        {
            /// <summary>
            /// 创建快递单号项目
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static OperationResult TrackExpressSubscibe(TrackMoreModel model)
            {
                #region 创建物流跟踪信息
                string urlstr = null;
                string requestdata = "{"tracking_number": "" + model.tracking_number + "","carrier_code":"" + model.carrier_code + ""}";
                string result = new TrackingMoreAPI().getOrderTracesByJson(requestdata, urlstr, "post");
                var code = TarckMoreExpressCompany.GetValueFromJson(result, "code");
                if ( code!="200")
                {
                    string message = EnmHelper.GetEnmName((TrackMoreServerResponse)int.Parse(code));
                    if (!message.Equals("跟踪已存在"))
                    {
                        return new OperationResult(message);
                    }
                }
                #endregion
                return new OperationResult();
            }
        }
    View Code

    其中GetValueFromJson 方法作用是从json字符串中获取字段值 ,在这里方法也贴一下:

            /// <summary>
            /// 从json字符串中获取字段值
            /// </summary>
            /// <param name="json">json字符串</param>
            /// <param name="field">要解析出值的字段</param>
            /// <returns></returns>
            public static string GetValueFromJson(string json, string field)
            {
                int start = json.IndexOf(field + "":");
                start += field.Length + 2;
                int end = json.IndexOf(",", start);
                if (end < 0)
                {
                    end = json.IndexOf("}", start);
                }
                return json.Substring(start, end - start).Trim('"');
            }    
    View Code

    OperationResult 类是自定义的业务操作结果类,可以根据项目需要自定义添加,这里我贴三个出来

            /// <summary>
           /// 默认操作成功
           /// </summary>
           public OperationResult()
           {
               IsSuccess = true;
           }
    
           /// <summary>
           /// 以操作失败信息实例操作结果
           /// </summary>
           /// <param name="failMessage">操作失败信息</param>
           public OperationResult(string failMessage)
            {
                IsSuccess = false;
                FailMessage = failMessage;
            }
    
            /// <summary>
           /// 业务操作是否成功
           /// </summary>
           public bool IsSuccess
           {
               set;
               get;
           }    

    ④有了跟踪物流信息类,那剩下的就是调用了 ,调用比较简单,主要是根绝项目业务 去做一些操作,比如从数据库查询订单,过滤一些条件,快递没有订阅的,排除掉一些订单类型,有些充值啊这些不需要快递,查询到的集合

    可以循环去创建物流单项目,调用的代码就一句,

    OperationResult result = TrackMore.TrackExpressSubscibe(new TrackMoreModel() { tracking_number =快递单号, carrier_code =快递公司简码) });

    然后可以根据返回的结果做一些其他操作

    if (result.IsSuccess)
        {
          //TODO 比如 更新数据库此条订单物流订阅状态,订阅时间等
        }
    else
         {
             //TODO 比如 日志记录失败原因
         }

    回调更新物流信息

    上面只是再More物流平台创建了此条物流信息记录,但是我们并不知道当前这个快递状态是如何,也不能每次都去快递平台查询,所以,回调的作用就凸显出来了,物流平台每次只要有物流更新的时候,会访问到你再平台上设定的回调URL。

    此时,你只用接收发过来的数据(包括meta请求头状态,data 数据 verifyInfo 签名部分),具体代码如下:

    ⑴先再More平台设置回调地址

    当然官方也提供了回调测试的 页面 在填回调地址的下面 点击 format of inbound webhooks 即可进入,界面如下图所示:

    ⑵设置完了回调地址,那我们就可以进行编码了,首先我们要对返回的数据 进行分析,上面也提到了 Body返回的主体部分是Json格式的,其实这里有一个坑,就是提交那边是form,但是接收是的数据类型是Json的

    关于这种请求数据类型区别和使用,可以看这篇博客:

    ASP.NET MVC学习系列(二)-WebAPI请求

    ok,既然是Json格式数据,那我们就把返回的Json格式数据转成实体模型。这里有几种方式推荐,①将官方示例中的json全部复制下来,然后随便百度一个Json转实体,不过我更推荐第二种,② 号称宇宙最强IED 的VS也帮我们实现Json转实体的快捷操作,具体操作方式如下:

    有了模型容器,我们就可以来接收数据了 创建一个和回调URL一样的方法名称UpdateTrack

    /// <summary>
    /// TrackingMore 回调 同步物流信息
    /// </summary>
    /// <param name="form"></param>
    /// <returns></returns>
    public ActionResult UpdateTrack([FromBody]Root dataJson)
    {
        var code = dataJson.meta.code;//请求状态
        var expressNumber = dataJson.data.tracking_number;//快递单号
        var status = dataJson.data.status;//物流状态
        var trackinfo = dataJson.data.origin_info.trackinfo;//物流信息集合
        var expressMessage = ""; //所有物流信息
        foreach (var item in dataJson.data.origin_info.trackinfo)
        {
            expressMessage += item.Date + " " + item.StatusDescription + "<br/>";
        }
        var track = dataJson.data.origin_info.trackinfo;
        var LastExpressMessage = track.Count > 0 ? track[0].Date + " " + track[0].StatusDescription : "";//最近一条物流信息
    
        //TODO 比如:先根据传过来的快递单号查寻 项目的订单表 确认是否有此订单,再根据数据表中的订单状态 
        //看是否需要修改一些其他信息,主要就是拿到第一条物流信息和所有的物流信息,也可以再数据表中记录此时这个快递单 回调的时间 和返回的状态 用于后期数据分析
    }

    注:此方法接受回调使用了FormBody ,快递100平台接收回调是FormCollection即可。

    外部调用

    所谓外部调用,就是再自己项目中,根据不同单号 借助物流平台查询快递实时信息。物流平台对此操作也有讲解,这里简单提下。

    官方给出的效果如下:

     实现步骤

    ①将下面这句引用代码放在标签开始之前的位置

    <script type="text/javascript" src="//cdn.trackingmore.com/plugins/v1/pluginsCss.js?time=20170913"></script><script type="text/javascript" src="//cdn.trackingmore.com/plugins/v1/plugins.min.js"></script>

    ②将下面代码放在 页面与标签之间的位置

    <div style="600px;margin-left:0px;text-align:left;">
        <form id="trackingmoreId" role="form"   action="//track.trackingmore.com" method="get"  onsubmit="return false">
            <div class="search-box">
                <div class="input-box">
                    <input id="button_express_code" type="hidden" value="" name="button_express_code"><input style="border-color: #428bca;" type="text" autocomplete="off" maxlength="26" placeholder="请输入快递单号" id="button_tracking_number" class="inp-metro" name="button_tracking_number"> <button style="background-color: #428bca" class="button-query" type="submit" onclick="return doTrack()" id="query">查询</button>
                </div> 
            </div>
            <input type="hidden" name="lang" value="cn" />
        </form>  
        <div id="TRNum"></div>   
    </div>
    <script type="text/javascript">
    function doTrack() {
        var num=document.getElementById("button_tracking_number").value;  
        var expCode=document.getElementById("button_express_code").value;  
        var width = document.getElementById("query").parentNode.offsetWidth;
        TRACKINGMORE.trackMynumber({
            TR_ElementId:"TRNum",      //必须,指定悬浮位置的元素ID。
            TR_Width:width,       //可选,指定查询结果宽度,最小宽度为600px,默认撑满容器。
            TR_Height:600,       //可选,指定查询结果高度,最大高度为800px,默认撑满容器。
            TR_ExpressCode:expCode,       //可选,指定运输商,默认为自动识别。
            TR_Lang:"cn",       //可选,指定UI语言,默认根据浏览器自动识别。
            TR_Num:num       //必须,指定要查询的单号。
        });
        return false;
    }
    </script>

    温馨提示:不要短时间内频繁调用 More平台会检测当前IP,过短调用会提示I异常 需要输入验证码   最终效果展示如下:

    PS:这种每次点击订单请求快递数据并不是最优的做法。因为上面我们也有提到过快递订阅这个功能,其实,最佳的做法是 订阅之后,快递平台推送到回调地址的最新物流信息,我们可以将这些物流信息保存再对应订单的快递物流字段里面。这样前台取的时候可以先判断

    物流信息字段是否为空,如果不为空 就直接取物流信息字段,这样既可以减少网络流量消耗,也可以加快系统反应时间,带来更好的用户体验。如果不喜欢用官方自带的这个显示框,也可以改成Bootstrap的样式框显示,具体做法如下:

     //查看物流(订单id,this,物流信息,快递单号,快递公司简码)
        function viewSenderMessage(id, obj, message, number, company) {
            debugger;
            if (!isNullEmptyUndefined(message)) {
                var d = dialog({
                    title: '物流最新跟踪',
                    content: "<div style='line-height:20px;'>" + message + "</div>",
                    okValue: '确定',
                    ok: true,
                });
                d.show(obj);
            } else if (!isNullEmptyUndefined(number) && !isNullEmptyUndefined(company)) {
                // doTrack(number, company);
                ajaxGetContent("@Url.Action("ViewExpress")" + "?companyNumber=" + company + "&expressNumber=" + number, function (data) {
                    var d = dialog({
                        title: '物流最新跟踪',
                        content: data,
                        okValue: '确定',
                        ok: true,
                    });
                    d.show(obj);
                });
            } else {
                var d = dialog({
                    title: '物流最新跟踪',
                    content: "无物流跟踪信息",
                    okValue: '确定',
                    ok: true,
                });
                d.show(obj);
            }
    }

    按照逻辑,如果物流信息为空 此时我们就需要从Action ViewExpress中获取单个快递信息。ViewExpress代码如下:

     public ActionResult ViewExpress(string expressNumber, string companyNumber)
            {
                string urlstr = null;
                string requestdata = "carrier_code=" + companyNumber + "&tracking_number=" + expressNumber;
                //此处是获取单个物流信息 采用get请求,method传入codeNumberGet
                string result = new TrackingMoreAPI().getOrderTracesByJson(requestdata, urlstr, "codeNumberGet");
                if (!result.Contains("code")) return Content("暂无物流信息,请稍后重试");
                var code = TarckMoreExpressCompany.GetValueFromJson(result, "code");
                if (code != "200")
                {
                    message = EnmHelper.GetEnmName((TrackMoreServerResponse)int.Parse(code));
                    //这里多加一层判断 4031表示请求成功,但是响应为空,意思就是 TrackMore平台上还没有这个快递单数据,所以要再次调之前创建物流项目这个接口
                    if (code == "4031")
                    {
                        OperationResult resMessage = TrackMore.TrackExpressSubscibe(new TrackMoreModel() { carrier_code = companyNumber, tracking_number = expressNumber });
                        if (resMessage.IsSuccess)
                        {
                            return ViewExpress(expressNumber, companyNumber);
                        }
                        else
                        {
                            message = resMessage.FailMessage;
                        }
                    }
                }
                else
                {
                    Root root = JsonConvert.DeserializeObject<Root>(result);
                    if (root.Data.origin_info.trackinfo.Count == 0) message = "暂无物流信息,请稍后重试";
              //此处将返回的物流信息以 时间+空格+物流消息 格式循环输出
    foreach (var item in root.Data.origin_info.trackinfo) { message += item.Date + " " + item.StatusDescription + " <br/>"; } }
            return Content(message); }

    获取单个物流信息采用的是get请求,所以再发送http请求的时候不能再用post 的流方式,需要多加一个get请求的,代码如下:

         public string HttpGet(string Url, string postDataStr, string method)
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Timeout = 30 * 1000;
                request.Method = method;
                request.Headers["Trackingmore-Api-Key"] = ApiKey;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                string retString = myStreamReader.ReadToEnd();
                myStreamReader.Close();
                myResponseStream.Close();
                return retString;
            }

    最终效果展示

    注:顺丰即日取消了对外第三方接口,故不能通过第三方物流平台获取到顺丰的物流信息,需要和顺丰开放平台(目前据顺丰IT人员透露,此平台已无人维护,已物流服务已转至顺丰官方的企业服务平台)对接 才能查到最新顺丰的物流信息

     顺丰的接口对接请转场至下文《物流一站式查询之顺丰接口篇》

  • 相关阅读:
    /etc/sysctl.conf 控制内核相关配置文件
    python 并发编程 非阻塞IO模型
    python 并发编程 多路复用IO模型
    python 并发编程 异步IO模型
    python 并发编程 阻塞IO模型
    python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
    python 并发编程 基于gevent模块实现并发的套接字通信
    python 并发编程 io模型 目录
    python 并发编程 socket 服务端 客户端 阻塞io行为
    python 并发编程 IO模型介绍
  • 原文地址:https://www.cnblogs.com/zhangxiaoyong/p/8229003.html
Copyright © 2011-2022 走看看