`
zxb_fish
  • 浏览: 4067 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类

用httpclient开发的在线自动抢订火车票系统(铁老大不给力,哥给力)

阅读更多
前两天女友要在线订火车在票,一直都没有办法订到票,最后没办法,便给她写了个自动抢票的脚本,可周边的朋友听她说通过软件订到票了,都先后向她要软件,可原来的脚本只是基于控制台输入,这样给别人也没法用,兴趣一起,就花了一天的时间做了个WEB界面,然后分享给朋友用。先上几张图,看大家看看。

这个是登录界面,要使用前先设置一下常用的邮箱和登录密码,自动抢票过程中,如需要再输入登录验证码和订单验证码,或订单成功时,将通过此email通知您,建议使用qq邮箱,这样只要您在电脑时开打QQ,收到邮件时,qq会弹出窗口通知您,您可以即时响应。  
第一次使用时,要先把在火车票官网注册的资料填在这里:

这资料都必码是已在官方上注册过的,在自动订票时,需要用到这些资料。



第一次登录后需要求先填写官网上的登录验证码和订单提交验证码,只要填写正确后,在填票过程中就一直可以使用,这也是官网的BUG,应该是他们在较正验证码后,没有让当前验证码失效,这样就只要不去刷新验证码,就可以一直使用第一次输入的正确验证码。


填写一下订票任务,主要就填写订票人资料(当然这个也是要在官网上添加过的),和订票信息,什么时候从哪到哪,从几列车等,保存完后,点开始,就则可以自动登录,找票,然后订票,订票成功后发邮件通知。


执行过程中,会时间更新执行的结果信息。




留言板功能,收集问题的反馈。


网友提供http代理,官方网站对一个IP的单位时间内访问次数据有限制,超过这个超制值IP会被封锁一段时间。
因为使用的人多,所以系统需要使用代理来向官网发送请求。

看到系统的整体内容后,再来介绍一下相关的技术
这个自动发送请求,提交数据,都依赖于httpclient4,火车票订票官方是使用ssl加密,这里是启用httpclient的ssl功能
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{easyTrustManager}, null);
SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
Scheme sch = new Scheme("https", sf,443);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);


大家都知道,这个官网的反映速度有时实在是惨不忍睹,所以我们也要设计一下请求等待的最长时间(30秒):
 httpclient.getParams().setIntParameter("http.socket.timeout",30000);//毫秒


官方网站对一个IP的单位时间内访问次数据有限制,超过这个超制值IP会被封锁一段时间。
因为使用的人多,所以系统需要使用代理来向官网发送请求,这个代理需要支持ssl,所以先网上找到一批代理IP过来,存在一个txt文字,格式为 ip:端口\n,以下读取IP代理,并且进行速试测试
	public void run(){
		  try {
			System.out.println("-----设置代理服务器----");
			String proxyFileString0 = FileUtils.readFileToString(new File(ApplicationUtils.getWebrootDir()+"/order/proxy_add.txt"), "UTF-8");
			String proxyFileString1 = FileUtils.readFileToString(new File(ApplicationUtils.getWebrootDir()+"/order/proxy_enable.txt"), "UTF-8");
			String proxyFileString = proxyFileString0+"\n"+proxyFileString1;
			for(String proxyString : StringUtils.split(proxyFileString, "\n")){
				proxyString = proxyString.trim();
	        	if(StringUtils.isNotEmpty(proxyString)){
	        		System.out.print("-----测试代理服务器: "+proxyString);
	        		String[] proxyInfo = proxyString.split(":");
	        		
		        	HttpHost httpHost = new HttpHost(proxyInfo[0], Integer.valueOf(proxyInfo[1])); 
		        	long start = System.currentTimeMillis();
		        	if(HttpUtils.testProxy(httpHost)){
		        		long usetime = System.currentTimeMillis()-start;
		        		if(usetime > 10000){
		        			System.out.println(" 不使用,响应时间太长时间:"+usetime+"毫秒----");
		        		}else{
		        			System.out.println(" 可使用,使用时间:"+usetime+"毫秒----");
		        			httpHostList.add(httpHost);
		        		}
		        	}
	        	}
	        }
			System.out.println("-----设置代理服务器成功,总数:"+httpHostList.size()+"----");
		} catch (Exception e) {
		}
	}


最后在每次请求时,选择一个代理
//设置代理对象 ip/代理名称,端口      
try{
	httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,ProxyHostUtils.next());
}catch(Exception e){}

每个用户在发送请求前,先从官网上读取两个验证码,一个是登录验证码,一个是提交订单验证码,一次性读取就可以了。
/**
	 * 读取登录验证码
	 * @throws Exception
	 */
	@Transient
	public void getRemoteLoginCode() throws Exception {
		File file = HttpUtils.doGetFile(OrderRunTask.loginCodeUrl+"&nocache="+Utils.getRandomString(10), cookieContext);
		if(file != null){
			File codeFile = new File(ApplicationUtils.getWebrootDir()+getLoginCodeUrl());
			FileUtils.copyFile(file, codeFile);
		}
	}
	
	/**
	 * 读取提交订单验证码
	 * @throws Exception
	 */
	@Transient
	public void getRemoteSumitCode() throws Exception {
		File file = HttpUtils.doGetFile(OrderRunTask.submitCodeUrl+"&nocache="+Utils.getRandomString(10), cookieContext);
		if(file != null){
			File codeFile = new File(ApplicationUtils.getWebrootDir()+getSubmitCodeUrl());
			FileUtils.copyFile(file, codeFile);
		}
		
	}


每个用户可以同时订多张火车票,系统为每张火车票启动一个线程,持续的运行,直到订票成功或者是被中断。
//建立线程池
public static ExecutorService runningTaskPool = Executors.newFixedThreadPool(1000);

//启动订票任务
OrderRunTask orderRunTask = new OrderRunTask(account, orderTask);
OrderRunTaskUtils.runningTaskMap.put(orderTask.getId(), orderRunTask);
Future<?> future = OrderRunTaskUtils.runningTaskPool.submit(orderRunTask);
orderRunTask.setFuture(future);

//中断任务
OrderRunTask orderRunTask = OrderRunTaskUtils.runningTaskMap.get(taskId);
try{
	orderRunTask.setStop();
	orderRunTask.getFuture().cancel(true);
}catch(Exception e){
	e.printStackTrace();
}

//判断是否订票成功,并且发送邮件
if(body.indexOf("45分钟") != -1){
	Date now = new Date();
	account.sendMail(orderTask.getQueryTrainDate()+"_订票成功",
		orderTask.getQueryTrainDate() +" "+
		orderTask.getFromStation()+"到"+orderTask.getToStation()+(StringUtils.isEmpty(orderTask.getTrainNo())?orderTask.getTrainNo():"")+" --订票时间:"
		+DateUtils.getDateTime("HH:mm:ss", now)
	);
	account.setReload(true);
									orderTask.setState(200);
									orderTask.setRuningTime(now);
									this.account.error(orderTask.toString()+": 订票成功。");
	break next;
}


这也只是本人兴趣开发,不使用在商品场合,以上分享的只是这个系统的设计思想,有时间再深入讨论。
顺便附上本机(随时变动的)的一个链接地址,大家可以看看 http://125.77.229.129:7070/order.html
  • 大小: 64.8 KB
  • 大小: 75.2 KB
  • 大小: 48.7 KB
  • 大小: 64.4 KB
  • 大小: 25.3 KB
  • 大小: 20.7 KB
  • 大小: 22.5 KB
分享到:
评论
10 楼 伤痕冰 2014-07-10  
能传一下 web页面吗 衔接不起来啊 楼主
9 楼 WOSHIHOUJINXIN 2013-01-26  
楼主的逻辑有点怪 ,为什么要同时获取订单验证码 和 登录验证码而且是先得到订单验证码 不登陆怎么下订单请问
8 楼 sasha110 2012-01-17  
报这个错误:
javax.net.ssl.SSLException: hostname in certificate didn't match: <dynamic.12306.cn/123.103.14.224> != <dynamic.12306.cn>
解决办法:
SSLSocketFactory sf = new SSLSocketFactory(sslcontext);         sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);//跳过hostname验证
7 楼 milk_36 2012-01-13  
楼主为什么我的 会报这个错误:
javax.net.ssl.SSLException: hostname in certificate didn't match: <dynamic.12306.cn/123.103.14.224> != <dynamic.12306.cn>
6 楼 beifengbei08 2012-01-11  
lib包能上传吗?
5 楼 alesg 2012-01-11  
楼主能共享下界面版不?
4 楼 lands2 2012-01-10  
求楼主提供包下载啊,还有就是:NekoHTML.jar这个加载进去有问题啊,是不是应该生成:DOMFragmentParser parser = new DOMFragmentParser();但是后面的parser.parse(new InputSource(in));也不对啊
3 楼 Mybeautiful 2012-01-10  
楼主确实很不错,有想法,并付诸实施。

“所以先网上找到一批代理IP过来”,有啥好办法找到一批可用代理,分享下。
2 楼 chaostan 2012-01-09  
求jar包分享 正在学习代码中
lots f thx
1 楼 mandarin 2012-01-09  
好东西 下来看看

相关推荐

    用httpclient开发的在线自动抢订火车票系统

    通过以上技术的整合与优化,一个基于HttpClient的在线自动抢订火车票系统可以有效地提高抢票效率,但同时也要注意遵守相关法律法规,避免对购票网站造成过大压力,以免被封禁。在实际应用中,还应关注网站更新,适时...

    httpclient自动购买火车票

    标题中的“httpclient自动购买火车票”指的是使用Apache HttpClient库来实现自动化购买火车票的程序。HttpClient是一个Java库,它提供了强大的HTTP客户端功能,可以用于发送HTTP请求并处理响应,非常适合进行网络...

    httpclient自动购买火车票2013-01-08

    标题中的“httpclient自动购买火车票2013-01-08”指的是一个使用HTTPClient库编写的程序,该程序在2013年1月8日时能够自动执行购买火车票的操作。HTTPClient是Java编程语言中用于发送HTTP请求的一个库,常用于自动化...

    Android的HttpClient开发实例

    本开发实例将带你深入理解如何在Android项目中使用`HttpClient`进行网络请求,实现数据的获取和上传。 首先,`HttpClient`是Apache的一个开源项目,它提供了一个强大的API来处理HTTP协议。`commons-httpclient-3.1....

    httpclient自动注册网站

    在IT行业中,HttpClient是一个非常重要的工具,特别是在网络编程和网页自动化操作中。本文将深入探讨如何使用HttpClient库来实现一个自动注册网站的功能。这个“httpclient自动注册网站”的项目涉及了HTTP协议的理解...

    HttpClient中文文档,快速开发

    这个标题"HttpClient中文文档,快速开发"表明我们有了一份关于HttpClient的中文版使用指南,对于快速理解和应用HttpClient进行开发来说非常有价值。 HttpClient允许开发者执行各种HTTP方法,如GET、POST、PUT、...

    httpclient开发所必须架包

    标题"HTTPClient开发所必须架包"暗示了这个压缩包包含了进行HTTPClient开发所需的依赖库。 HTTPClient库由Apache软件基金会维护,是许多Java Web应用和微服务架构中的核心组件。它支持多种HTTP方法(如GET、POST、...

    httpclient 开发包以及例子

    8. **重试策略**:HttpClient允许设置重试策略,当请求失败时自动重试,提高网络不稳定情况下的成功率。 9. **异步请求**:HttpClient 4.x引入了异步API,允许并发执行多个请求,提高了处理大量并发请求的能力。 ...

    httpclient4.5.4 开发文档

    httpclient4.5.4 开发文档 超文本传输协议(HTTP)或许是最重要的互联网上使用的协议。Web服务、网络功能和网络计算的增长继续扩展HTTP协议的作用超出用户的Web浏览器、应用数量的增加,需要支持HTTP。 尽管net包提供...

    httpclient开发jar全套

    下面我们将详细探讨HTTPClient库以及其在Java开发中的应用。 1. **HTTPClient介绍** HTTPClient是一个强大的库,允许开发者通过HTTP和HTTPS协议与Web服务器交互。它支持多种HTTP方法(如GET、POST、PUT等)、...

    httpclient3 自动登陆淘宝, 开心网

    标题中的“httpclient3 自动登陆淘宝, 开心网”指的是使用Apache HttpClient 3.x库来实现自动化登录淘宝和开心网的功能。HttpClient是一个强大的HTTP客户端API,它允许开发者模拟浏览器行为,发送HTTP请求并接收...

    全栈自动化测试实战 基于testng,httpclient,selenium.appium

    全栈自动化测试实战,是现代软件开发中一个关键的环节,尤其在追求高效、稳定和质量的项目中显得尤为重要。本书以testng、httpclient和selenium.appium为技术核心,详细介绍了如何进行端到端的自动化测试。下面将...

    火车票抢票程序

    《火车票抢票程序开发详解》 在信息技术日益发达的今天,火车票抢票程序已经成为了许多旅客在节假日出行时的必备工具。本篇文章将详细解析一个简单的火车票抢票程序,带你了解其背后的原理与实现方法。 首先,我们...

    使用HttpClient必须的jar包

    在Java项目中使用HttpClient时,为了确保功能的完整性和正确性,通常需要引入一系列的jar包。这些jar包包含了HttpClient的核心组件、依赖库和其他必要的工具,它们共同构成了HttpClient的运行环境。 以下是一些关键...

    httpclient如何保持session会话模拟登录后的操作

    在IT行业中,网络编程是必不可少的一部分,而HTTPClient作为Java中广泛使用的HTTP客户端库,它允许我们进行HTTP请求,处理响应,并实现与Web服务器的交互。在某些应用场景中,如模拟用户登录、爬虫或者自动化测试,...

    httpClient需要的jar包

    在Java应用中,HttpClient常用于网页抓取、API调用以及自动化测试等场景。 本压缩包文件"httpClient"很可能包含了HttpClient库所需的必备JAR文件,这些文件通常包括HttpClient的核心库、依赖的第三方库以及可能的...

    HttpClientHelper 工具类

    这样做的好处是避免了频繁创建和销毁HttpClient对象,降低了系统资源消耗,尤其在高并发场景下,可以防止大量并发请求对服务器造成压力。 HttpClientHelper 的主要功能可能包括以下部分: 1. **同步请求**:使用...

    C#火车票在线订购.zip

    这个项目的核心是使用C#编程语言实现一个火车票在线订购系统。C#是一种广泛应用于Windows平台开发的面向对象的编程语言,尤其在构建桌面应用、Web应用以及游戏开发等领域有着广泛应用。在这个项目中,C#将作为主要的...

    httpclient开发相关包

    HttpClient的使用需要三个包,分别是commons-httpclient-3.1.jar、commons-logging-1.1.1.jar、commons-codec-1.3.jar,每个包内都有API

    使用httpclient访问servlet

    总之,使用HttpClient访问Servlet能够简化Java应用之间的通信,特别是在分布式系统中。正确理解和应用HttpClient的各种特性和配置,能够帮助我们构建高效、可靠的网络通信方案。在实际开发中,还需要根据具体项目...

Global site tag (gtag.js) - Google Analytics