快递查询组件
最近翻一翻邮件,发现有以前实习的时候帮公司做的一个获取快递网站的快递信息.Net组件,我copy出来了的。现在就分享一下。
一.调研快递100网
1. 通过httpwatch抓取了快递100网查询快递的地址 http://m.kuaidi100.com/query,API访问格式是 queryUrl + "?type=" +快递公司类型+ "&postid=" + 快递单号;
我的另一篇博客里面有写到如何抓取: 一个有用的网络监控软件
2. 默认返回Json字符串格式是:
{"message":"ok","status":"1","state":"3","data": [{"time":"2012-07-07 13:35:14","context":"客户已签收"}, {"time":"2012-07-07 09:10:10","context":"离开 [北京石景山营业厅] 派送中,递送员[温],电话[]"}, {"time":"2012-07-06 19:46:38","context":"到达 [北京石景山营业厅]"}, {"time":"2012-07-06 15:22:32","context":"离开 [北京石景山营业厅] 派送中,递送员[温],电话[]"}, {"time":"2012-07-06 15:05:00","context":"到达 [北京石景山营业厅]"}, {"time":"2012-07-06 13:37:52","context":"离开 [北京_同城中转站] 发往 [北京石景山营业厅]"}, {"time":"2012-07-06 12:54:41","context":"到达 [北京_同城中转站]"}, {"time":"2012-07-06 11:11:03","context":"离开 [北京运转中心驻站班组] 发往 [北京_同城中转站]"}, {"time":"2012-07-06 10:43:21","context":"到达 [北京运转中心驻站班组]"}, {"time":"2012-07-05 21:18:53","context":"离开 [福建_厦门支公司] 发往 [北京运转中心_航空]"}, {"time":"2012-07-05 20:07:27","context":"已取件,到达 [福建_厦门支公司]"} ]}
二. 定义实体类.
按照Json格式定义,实体类:
Notes:1.MQueryParameter 查询条件 ;2.MResultMsg 查询后的返回结果; 3.ExpressageInfo单个时间段的物流情况;4.ErrorMsg:记录存储访问错误,包括配置文件错误,以及web访问错误
public class MQueryParameter { /// <summary> /// 快递公司 /// </summary> public string TypeCom { get; set; } /// <summary> /// 快递订单号 /// </summary> public string OrderId { get; set; } } public class MResultMsg { public bool Result { get; set; } public StateType State { get; set; } public string JsonMessage { get; set; } public List<ExpressageInfo> Data { get; set; } public ErrorMsg Error { get; set; } } public class ExpressageInfo { public DateTime Time { get; set; } public string Context { get; set; } } public enum StateType { 在途, 揽件, 疑难, 签收, 退签, 派件, 退回 } public class ErrorMsg { public string ErrorCode { get; set; } public string ErrorMessage { get; set; } }
三.配置文件.
对于查询的API URI 我们应该用配置文件存储起来,以及快递的Map信息. 主要是用于放置API变化.
Note: xml里面用到了转义:&(逻辑与) & <(小于) < >(大于) > "(双引号) " '(单引号) ' [/size]
<configuration> <appSettings> <!--手机api服务器访问地址--> <add key="queryUrl" value="http://m.kuaidi100.com/query?type={0}&postid={1}" /> <!--顺丰快递对应的编码--> <add key="顺丰速递" value="shunfeng"/> <add key="中通速递" value="zhongtong"/> </appSettings> </configuration>
三.Helper方法.
通过Helper的提供的方法对QueryParam参数的Check以及数据获取,方法里面的所有异常都必须处理。组件按理是不能出现让程序崩溃的情况的。所以所有异常必须处理。然后封装到ErrorMsg对象中.
public static MResultMsg GetExpressageMessage(MQueryParameter para) { // 获取配置文件 Configuration config = null; string queryUrl = string.Empty; string com = string.Empty; MResultMsg msg = new MResultMsg();if (string.IsNullOrEmpty(para.TypeCom)) { msg.Result = false; msg.Error = new ErrorMsg() { ErrorCode = "001", ErrorMessage = "物流公司不能为空" }; return msg; } if (string.IsNullOrEmpty(para.OrderId)) { msg.Result = false; msg.Error = new ErrorMsg() { ErrorCode = "002", ErrorMessage = "订单号不能为空" }; return msg; } try { string configPath = System.IO.Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Expressage.config"); ExeConfigurationFileMap map = new ExeConfigurationFileMap(); map.ExeConfigFilename = configPath; config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); queryUrl = config.AppSettings.Settings["queryUrl"] == null ? string.Empty : config.AppSettings.Settings["queryUrl"].Value; com = config.AppSettings.Settings[para.TypeCom] == null ? string.Empty : config.AppSettings.Settings[para.TypeCom].Value; } catch (Exception ex) { msg.Result = false; msg.Error = new ErrorMsg() { ErrorCode = "003", ErrorMessage = ex.Message }; return msg; } if (string.IsNullOrEmpty(com)) { msg.Result = false; msg.Error = new ErrorMsg() { ErrorCode = "004", ErrorMessage = "配置文件缺少对于的物流公司类型" }; return msg; } // 网上获取物流信息 string jsonResult = null; try { queryUrl = string.Format(queryUrl, com, para.OrderId); WebRequest request = WebRequest.Create(@queryUrl); WebResponse response = request.GetResponse(); string message = string.Empty; using (Stream stream = response.GetResponseStream()) { Encoding encode = Encoding.UTF8; using (StreamReader reader = new StreamReader(stream, encode)) { message = reader.ReadToEnd(); } jsonResult = message; } } catch (Exception ex) { msg.Result = false; msg.Error = new ErrorMsg() { ErrorCode = "005", ErrorMessage = ex.Message }; return msg; } msg = JSONStringToObj<MResultMsg>(jsonResult); msg.JsonMessage = jsonResult; msg.Result = true; return msg; } private static T JSONStringToObj<T>(string JsonStr) { JavaScriptSerializer Serializer = new JavaScriptSerializer(); T objs = Serializer.Deserialize<T>(JsonStr); return objs; }
四. 下载地址:
Frank.Expressage.zip 里面有一个测试数据,可能时间过太久里面那个快递单号也会出现过期情况查询不到数据.
五.总结
代码是以前写的没做修改,就贴上来了。感觉有点不厚道,因为那个Uri是自己用httpwatch抓的。单独获取API 希望大家还是访问官网去申请吧。抓取的uriApi对用户有访问频率限制的。访问过于频繁。就会被封掉。 下面是官网地址,请支持正版: http://www.kuaidi100.com/openapi/applyapi.shtml