揭开邮局EMS快递单查询原理

揭开邮局EMS快递单查询原理揭开邮局EMS快递单查询原理

现在都是流行网上购物了,大家一定关心自己购买东西快递现在已经发到什么地方了,现在想查一查。当然现在有很多提供这种服务,我今天就给大家实现一个无需打开浏览器就可以实现EMS快递查询,简单讲述其原理。以下是我简单画的流程图(随便用office画,很山賽,哈哈):

(1)EMS网站

揭开邮局EMS快递单查询原理

(2)流程图

揭开邮局EMS快递单查询原理

(3)结果图:

揭开邮局EMS快递单查询原理


好了,我们开始源码吧:

/**
* 查询EMS快递状态
* @author luodongfu

* 我把我实现的代码全部贴出来,哈哈。
*/

public class GetEms
{
public static void main(String[] args)
{

//我这里使用WebClient 来抓去
WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_7);
webClient.setActiveXNative(true);
webClient.setJavaScriptEnabled(true);
HtmlPage loginPage = null;
try
{

//打开ems邮局网站
loginPage = webClient
.getPage("http://www.ems.com.cn/qcgzOutQueryAction.do?reqCode=gotoSearch");
} catch (Exception e1)
{
e1.printStackTrace();
}
if (loginPage == null)
{
return;
}

//找到查询页面的表单以及其中的
HtmlForm loginForm = loginPage.getFormByName("form1");

//找到快递单输入框
HtmlTextInput mailNum = loginForm.getInputByName("mailNum");

//找到快递单验证码输入框,这个ems很狡诈,每天这个F346F82440A3AAC78473802都会变,

所以最好加一个判断如果出错的话就直接抓去页面这个值。我这里就写死了,呵呵
HtmlTextInput codestr = loginForm.getInputByName("F346F82440A3AAC78473802");
HtmlImage p = null;

//找到验证码图片
DomNodeList<HtmlElement> ps = loginPage.getElementsByTagName("img");
boolean success = false;
File f = null;

//遍历查询图片,如果找到该图片则保存到D盘111.png文件
for (HtmlElement ht : ps)
{
if (ht instanceof HtmlImage)
{
HtmlImage img = (HtmlImage) ht;
String alt = img.getAltAttribute();
if (alt != null && alt.contains("不清?点击换图"))
{
f = new File("D://111.png");
if (f.isFile() && f.exists())
{
f.delete();
}

//保存图片
try
{
img.saveAs(f);
success = true;
} catch (Exception e)
{
e.printStackTrace();
}
System.out.println("识别码图片文件写入磁盘OK");
if (success)
{
break;
}
}
}
}

//如果图片保存成功,则弹出图片显示

if (success)
{
try
{
Runtime.getRuntime().exec(
"cmd.exe /c start " + f.getCanonicalPath());
} catch (IOException e2)
{
e2.printStackTrace();
}

//提示输入验证码

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
System.out.println("请将你看到的识别码输入:");
try
{
str = br.readLine();
} catch (IOException e)
{
e.printStackTrace();
}
if (str != null && !str.trim().equals(""))
{
str = str.trim();
codestr.setValueAttribute(str);

//这里是邮局EMS快递单,我这里写死,你可以做一个提示用户输入
mailNum.setValueAttribute("EF706866075CS");


System.out.println("你输入的识别码是:" + str);
HtmlImageInput button = (HtmlImageInput) loginForm.getInputByName("optijiaot");
try
{
Page rsp = button.click();//模拟用户点击提交数据
if (rsp instanceof HtmlPage)
{
loginPage = (HtmlPage) rsp;
success = true;
}
} catch (Exception e)
{
success = false;
e.printStackTrace();
}

//如果查询成功,则开始解析结果
if (success)
{

//解析返回的结果,ems这个表格table 做的很垃圾,一个table 里面包含一个table 很多,而且table.

// id 一个都没有,他娘的什么鸟人编html的程序。这里我解析部分省略了,呵呵
parseTable(loginPage.asXml());

}

}

//删除空格

public static String replaceBlank(String tt)
{
Pattern p = Pattern.compile("//s*|/t|/r|/n");
Matcher m = p.matcher(tt);
if(m.find())
{
String after = m.replaceAll("");
return after;
}
return null;

}
}


好了结果出来了:

识别码图片文件写入磁盘OK
请将你看到的识别码输入:
R72C
你输入的识别码是:R72C


2010-05-06 10:11:34 武义县 到达处理中心,来自武义县邮政局速递公司
2010-05-06 12:15:48 武义县 离开处理中心,发往金华市邮政局分拣*
2010-05-06 13:57:36 金华市 到达处理中心,来自武义县
2010-05-06 18:55:07 金华市 离开处理中心,发往北京市
2010-05-10 12:57:15 北京邮政陆路速递邮件处理中心 到达处理中心,来自金华市
2010-05-10 16:54:08 北京邮政陆路速递邮件处理中心 离开处理中心,发往北京邮政速递世纪城分公司香山营投部
2010-05-11 07:15:35 北京邮政速递世纪城分公司香山营投部 到达处理中心,来自北京市
2010-05-11 07:45:59 北京邮政速递世纪城分公司香山营投部 安排投递
2010-05-11 09:20:00 北京邮政速递世纪城分公司香山营投部 妥投
您的邮件于2010-05-11 09:20:00(北京邮政速递世纪城分公司香山营投部)已妥投投递结果:董波代收

最后注意以下的F346F82440A3AAC78473802东东:

最好从其页面抓去,不然为出错,哈哈。我懒,所以我就写死了。

HtmlTextInput codestr = loginForm.getInputByName("F346F82440A3AAC78473802");