通过Java刷校内的心得

[size=medium] 这两天写了个小程序来刷校内人气,通过Java实现,借助了HttpClient包.以下都是我自己的一些想法,欢迎大家指正。
  这个程序我总共写了四个版本,第一个版本和后面三个版本差别较大,在我认为,刷校内有两种方式:一种是被动刷,网上能找到的刷子程序几乎都是这种类型。被动式刷法通过访问别人的校内来提高自己的人气。这种方式的缺点在于由于别人回访的概率不定,因此效率很低。我的第一版刷子采用的就是这个方式。需要说明的是,第一个版本实际上没有完成,但基本的功能框架已经实现。另一种方式是主动刷,这种刷法是通过模拟别人访问自己的方法提高人气,这种方法的特点在于效率奇高,网上有卖人气的似乎一眨眼间便能刷出上千人气。我写的没有这么离谱~
  主动刷通过模拟别人访问自己的校内,那又如何模拟呢?那种一眨眼刷出上千人气的,我不清楚它是如何实现的。我采用的方式是通过一批机器人帐号来访问自己的校内而达到模拟访问的效果。机器人帐号的获得可以通过自动注册机实现,也可以通过手工注册实现。自动注册机需要自己编写,主要完成三个功能:注册邮箱、注册校内、激活帐号。这里有几个难点:1.验证码自动识别;2邮箱的登录问题,邮箱的安全级别较高,其访问通过Https完成。我感觉实现起来很麻烦,需要花很多时间。因此我采用的是手工注册的方法,总共建立了50个机器人帐号,通过这些帐号实现了刷人气。
  下面是一些具体的技术细节了。
  HttpClient是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP 协议的客户端编程工具包。程序的主要功能通过HttpClient实现,比如登录、刷人气、图片下载。这些功能无非是两种方式:POST和GET。POST和GET是Http请求的方式,也是最常用的两种方式,POST用于向服务器提交数据而GET用于从服务器获取数据。
  DOM4J是很流行的xml解析操作方案。我通过dom4j解析配置文件,配置文件的功能是配置被刷的帐号以及机器人帐户。dom4j需要jaxen包。
  判断是否需要验证码,这个通过String类提供的方法即可,无须使用正则表达式。如果页面包含了验证码,则一定包含了这个字符串"personalInfo5qValidateCode",在此字符串后即有验证码的地址,格式:<img src="地址"../>,藉此可以判断并取得验证码地址,然后将其下载。
  图片的下载及显示。通过流来下载图片,然后将其转换为byte[]提供给ImageIcon发生成图片并在JLabel中显示。既然是流,则不可预知流的长度,不可预知流的长度则不可预知byte[]的长度,但可以通过循环读取整个流将其保存到ByteArrayOutputStream中。然后借助ByteArrayOutputStream的toByteArray方法转换为byte[]。代码如下:
  InputStream is=get.getResponseBodyAsStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b=0;
while( (b = is.read())!=-1) baos.write(b);
ModalImage mi=ModalImage.getInstance();
mi.show(new ImageIcon(baos.toByteArray()));
ModalImage是模式对话框,用于显示图片并提供用户输入验证码。之所以要求用户手工输入验证册,是因此我还无法完成全部的验证码识别功能。现在校内的验证码分两种,一种是规则的,这种容易识别;另一种是无规则的,不懂怎么识别啊,晚上获得一个信息:依据人工神经学的某个理论可以实现一定几率的识别,But我连人工神经学的书都没摸过~
  信息的即时显示,用户友好的程序应该即时给予用户信息,让用户知道程序的状态。因此刷的过程中需即时显示相关的信息,诸如"某个机器人帐号成功","已经访问谁的空间","进度"。这里我通过JTextArea输出登录、访问类信息,通过JProgressBar显示进度。需要注意的是JTextArea的信息会在整个程序运行完成后输出,啥意思呢,就是JTextArea不会即时输出信息。如何解决呢,这里需要通过线程来解决,即在单独的线程里实现JTextArea.append()方法。另外信息很多而JTextArea的高度是有限的,因此需要一个滚动条,如此则要把JTextArea放在JScrollPane里。有了滚动条后,如果滚动条不跟随文本滚动,那用户看到的只是首先输出的那部分信息,因此在JTextArea.append()之后,再调用JTextArea.selectAll(),让滚动条滚动到文本未,最后JTextArea.invalidate()。JTextArea既然是输出信息的,我自然不希望它响应用户的输入,因此再setFocusable(false)让它不能获得焦点。
  模拟访问,所谓模拟访问即是把自己伪装成某种浏览器,或者说伪装成某种客户端。在Firefox里有种extension,通过它可以伪装成通过手机浏览。这里我们自然不需要模拟成手机访问,我模拟的是Firefox。在浏览器向服务器提交的请求头里,有个字段是User-Agent,通过它我们可以判断客户来自何种浏览器。因此我们将此字段以及其值加入到请求体中:
NameValuePair nvp[]={
new NameValuePair("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1"),
new NameValuePair("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),
new NameValuePair("Accept-Language","zh-cn,en-us;q=0.7,zh;q=0.3"),
new NameValuePair("Accept-Charset","gb2312,utf-8;q=0.7,*;q=0.7"),
.....其他需提交的内容
};
postMethod.setRequestBody(nvp);//加入到请求体中
 如果你想装得更像点,可以添加更多的字段。怎么知道字段有啥呢,很多extension可以监测Response和Request,这里推荐个FireBug。
 在登录中,则需要将用户帐号和密码放在nvp中,然后加入请求体。如何判断登录成功与否?我们不需要解析返回的内容,只需检测是否有重定向即可。如果服务器返回状态码302,恭喜你,登录成功了。
 cookie问题.如果不能把cookie也随请求发送到服务器,那么这一切就无法实现了。服务器无法判断你的身份,无法判断你是否已经登录,那么就无从刷起了。HttpClient为你处理了这一切,它会自动处理cookie。需要注意的是cookie有三种协议,不同协议之间存在区别。这里设置httpClient.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY)。HttpClient又如何知道何时要附加cookie呢?我前脚登录了校内,得到了一堆cookie,然后又访问google,那么HttpClient会将校内的cookie带到google吗?这里有个Host的概念,在请求体中也能看到这个字段.Host即主机.URL的格式:protocol :// hostname[:port] / path / [;parameters][?query],如果你想深入了解,这里有个地址http://www.ietf.org/rfc/rfc2396.txt。这里设置成http://xiaonei.com,其他的地址:
  登录:http://login.xiaonei.com/Login.do
  访问:http://xiaonei.com/getuser.do?id=用户ID
  获取验证码;获取可得

快速刷,我个人觉和是不是很有必要。毕竟不是商业行为,我希望刷的安全、刷得稳。速度不要求非常高。如果要实现快速刷,我个人认识,通过运行足够多的线程是可以实现的,这有个上限。当然应该有其他的诀窍,以后再研究下~

  大概就这些了吧,这里没有给出具体的代码,但思路、一些注意点都提到了~~~此前傅学宁对我一篇日志的评论:没有技术含量啊。这篇呢,很多地方会有错误哦~~~

[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值