商城项目基本快差不多,多少是要有物流信息的,想着找找相关的接口接入进来才是。
一.寻找免费的快递查询API接口
用万能的百度搜索了下,发现几个差不多的快递API,基本都能用,于是一个个测试一下吧。
1.1快递鸟
这个是同事搜索推荐的,好家伙,直接注册免费的开发账号,试用。
代码撸了一遍,还行。
以为万事大吉的时候,发现有快递查询限制..
申通、天天、百世、顺丰各种不支持,这不就是个坑爹货吗?
1.2 快递100
这个大概看了一下,做的还不错,有点正规的样子,不过一点开注册申请,开发KEY申请页面就知道,还是一路货色,就是让你去开企业版本的,而且注册起来贼麻烦,各种要填写的,还要加友情链接,这不是坑爹的吗?要推广也不是这个搞法嘛。果断下一个。
1.3 爱查快递
这个也看了下,感觉接口都是大差不差,但是翻到接口申请说明就更坑爹了,直接就关闭注册,不让用了。还要搞啥友情企业,合作伙伴。。不行就不行嘛。
1.4 天下没有免费的午餐
基本翻了个遍,发现不行嘛,没得好用的,
然后突然发现爱查快递有一个快递查询页面,反正页面上能查询,试试吧,
随便查询了一个单号,结果还行,习惯性的F12,调试下看看, 发现我靠,就是一个ajax请求嘛,我直接访问你的后台不就完了吗?还接啥API啊,这么麻烦干嘛呢,HOHO..
二.自动动手,丰衣足食-间接使用爱查快递
2.1 跟踪爱查快递页面JS
大体看了下页面上的js,别的没啥,就发现一个tk,貌似需要生成一个key,看样子还是有点搞头呢,需要对暗号,
那就对咯,不就是js 转 java嘛,来战。
分析了下,发现有a,b,c,d,e,g等一堆方法及变量,反正最后就生成了一个key.
2.2 爱查快递页面JS-签名算法
捣鼓,跟踪了半天多,搞定,基本后台算出来的key一样,
代码.
String url = "https://www.ickd.cn/";
long[] g;
String h = "edb";
String i = "15900";
long ck = -1;
public ICKDWuliuTrack() {
g = a();
}
public String sign(String num, String miniseconds) {
String key = num + miniseconds + url;
// key="2141182099981531273270897"+url;
int[] a = b(key);
long fval = d(a);
// -4592476
String v = Long.toHexString(fval);
// 去除负数ff
while (v.startsWith("f"))
v = v.substring(1);
if (v.length() < 7)
v = "ff" + v;
return v;
}
public int d(int[] a) {
int c;
int e, f;
// c = ck;
c = -1;
e = 0;
for (f = a.length; f > e; e += 1) {
int tp = (int) c >>> 8;
c = tp ^ (int) (g[(int) (255 & (c ^ a[e]))]);
}
ck = c;
return -1 ^ c;
}
public static int[] b(String a) {
int[] bdata = new int[a.length()];
String[] ss = a.split("");
for (int i = 0; i < ss.length; i++) {
bdata[i] = ss[i].charAt(0);
}
return bdata;
}
public static long e(String a) {
int b, d, f, h = 16;
long i = 0;
b = a.length();
char e;
int v;
String[] c = (StringUtils.reverse(a)).split("");
for (d = 0; b > d; d++) {
e = c[d].charAt(0);
f = c[d].charAt(0);
if (f >= 97) {
// e =(char)( f - 87);
v = f - 87;
} else
v = Integer.parseInt(String.valueOf(e));
i += Math.floor(v) * Math.pow(h, d);
}
return i;
}
/**
* 对应js中 g方法生成 g数组 a方法
*
* @author zj
* @date 2018年7月10日
*/
public long[] a() {
long j = e(h + e(i));
long[] g = new long[256];
long a;
int b, c;
for (b = 0; 256 > b; b++) {
for (a = b, c = 0; 8 > c; c += 1) {
if ((1 & a) > 0) {
a = j ^ a >>> 1;
} else {
a = (a >>>= 1);
}
// 1 & a ? a = j ^ a >>> 1 : a >>>= 1;
}
g[b] = a >>> 0;
}
return g;
}
麻蛋,JS里面int,long自己会转换,在java里面需要手动注意,这里卡了半天,反正一步步调试,总算是搞定。
好了,急匆匆的调用一下试试,一看结果,尼玛,每次都是随机的单子,这就无语了,刷一下变一下,这查个毛毛啊。
2.3 坑爹的结果-cookie/Referer
转念一想,不对啊,页面怎么能查出来,我传一样的参数为毛出不来呢,再仔细看了下js,看下请求的数据,发现有cookie及referer我没有传,那就补上咯,好家伙,把参数补上,妥妥的就出来了。。
我又一想,那我要是把sign key、cookie、referer换掉行不行呢。。一一试了下,结果更坑爹了。我辛辛苦苦算出来的key屁用没有,人家根本就没有在后台校验这个值,尼玛随便传个啥都行,算了反正都算出来就这样吧.
Random r = new Random();
/*
* conn.setRequestProperty("Cookie",
* "Hm_lvt_39418dcb8e053c84230016438f4ac86c=1531212321; Hm_lpvt_39418dcb8e053c84230016438f4ac86c=1531273461"
* );
*/
conn.setRequestProperty(
"Cookie",
"Hm_lvt_39418dcb8e053c84230016438f4ac86c="
+ r.nextInt(1000000)
+ "; Hm_lpvt_39418dcb8e053c84230016438f4ac86c="
+ r.nextInt(1000000));
conn.setRequestProperty("Referer", "https://www.ickd.cn/");
2.4 结果检验
既然能用了,那就多少试一下吧。
查了几个快递,中通、申通、百世都不错,能出来,
然后发现韵达的不行,直接返回需要验证码,在网页上使用也是一样,直接弹出了腾讯的验证码弹框,拖拽验证的那种,这就没得搞了。然后发现顺丰的也不行,一样需要验证码识别。
愁呢。。。
三.柳暗花明又一村
3.1 大家既然都一样,那么都能借用咯
想了半天,突然灵光一闪,我靠,既然爱查快递能借用页面API,那其他的快递查询是不是一样呢???
点开快递100的页面,F12调试,妥妥的,这个更简单了,直接校验key都不要了,post过去就出结果了,- -!
3.2 整合使用
那就好办了吧,既然爱查快递费了老大的劲,那就先用这个查吧,没结果就整合调用快递100的,SO GA,基本都能查出来呢。
刚好还有互补的效果。。汗,自动识别单子的快递类型呢。
3.3 上线自己的快递查询
捣鼓一番,我自己的网站也上线一个快递查询吧,哈哈
马蛋,发现这个自动识别有时还是不行啊。。汗,先凑或着,再改进改进。。。
3.4蛋疼..
0712,我靠,今天查了下,发现这个爱查快递查不出来了啊,是不是后台屏蔽我了呢。。
看后台,直接返回message:'hehe' ,囧了~
{"status":0,"message":"hehe","errCode":11,"data":[],"html":"","mailNo":"3364225067419","expTextName":"申通快递","expSpellName":"shentong","ord":"ASC","tel":"95543\/4008895543"}
------------------------
本文基于CC BY-NC-ND 4.0 许可协议发布,作者:野生的喵喵。 固定链接: 【快递查询上线】 转载请注明
相关文章: