http;//data.edu.qq.com/anucollege.edu.au

用HttpClient抓取众人网高校数据库(省,高校,院系三级级联)-更新1_数据库大全_优良自学吧 |
当前位置: >
> 用HttpClient抓取众人网高校数据库(省,高校,院系三级级联)-更新1优良自学吧提供用HttpClient抓取众人网高校数据库(省,高校,院系三级级联)-更新1,用HttpClient抓取人人网高校数据库(省,高校,院系三级级联)--更新1
更新备注:将src文件改成了一个完整的项目,解压后可以直接导入到Eclipse中去,省去大家配置(项目乱码请改项目属性为GBK)。另外,如果你要登陆人人网 的话,需用HttpClient抓取人人网高校数据库(省,高校,院系三级级联)--更新1
更新备注:将src文件改成了一个完整的项目,解压后可以直接导入到Eclipse中去,省去大家配置(项目乱码请改项目属性为GBK)。另外,如果你要登陆人人网 的话,需要申请一个人人网账号。这里提供公用的:\
java123456
请自行修改RenRenNotify.java 对应的东西。
首先文章有点长,需要点耐心。这里我是一步一步的做的。。。。比较的细,如果你是代码达人,那你就直接下载代码吧。
有人说图片看不清,我抱歉,第一次咱的图片不完美,你把图片在浏览器上拖动到新窗口,就可以看到你大图了。
需求来源,最近学校的课程项目需要一个省,高校,院系的三级级联的东西,这下麻烦了。全国那么多的高校,而且每一个高校的院系设置又不一样,我们小组只有六个人,而且技术都不咋地,要统计那么多的数据,我们估计这学期就别想完成这个项目了。但是我们知道人人网,开心网,腾讯微博上都要高校的数据库,于是想法就产生了:
1.要么咱拼人品让他们的技术人员给我们他们的数据库,想法是好的,但是人家不肯呀
2.要么咱通过某种手段获取他们的数据
今天,咱选择第二种。用到工具有:
EditPlus:小巧好用的文本编辑器,是超越的文本编辑器,不解释,用了就知道
Apanta:这个强烈推荐,用它来写Html,Javascript,Css感觉非常好,而且支持各种各样的Javascript的库,如:
Jquery,但是我想把他集成到MyEclipse上去,出了一点问题,遗憾,弄的我只能同时开启两个。
HttpAnalyzer:这个是用来抓包用的,无论什么包统统抓,不过只能抓Http协议的包,当年傻,分析飞信协议的时候,
用这个抓,结果只抓了一点东西。如果你想抓取更底层的推荐一个:WireShark,免费的好用的。
MyEclipse:这个不多说了,弄过J2EE的应该都知道的。
另外就是第三Jar包了,HttpClient 4.01 请到:http://hc.apache.org/downloads.cgi 下载,只要是4版本上的都应该可以,如果是3.1版本的估计你要重新写一些代码,因为4较3还是有很大的改进的。
一般来说,一个网站对访问它内部的东西需要权限的验证的,比如你下载某个网站的东西,他会提示说 只有会员才可以下载,于是乎,这里存在一个session,保存了你的登陆信息也就是你的访问网站内部资源的权限了。人人网估计也不是省油的灯(这里有问题,后面解释),于是我们应该登陆它才能获得访问它内部资源的权限。那么我们首先来抓包分析应该怎么用登陆,于是HttpAnalyzer闪亮登场.
打开HttpAnalyzer,让他开始工作,我们打开浏览器,输入。第一次咱先不急着登陆。我们随便输入一个账号密码看看:
我们看到当你输入用户名密码后就将你输入的东西post到:/PLogin.do,
其中PostData有四个:email,password,origURL,domain。至于后面的数据是我们刚刚在登陆页面上填写的数据。
我们再来看看它登陆页面的源代码:
注意我红色标注的地方:我们注意到,除了我们刚刚在上面发送的数据还有其他的隐藏发送的的东西:例如:origURL等等,这里他们是&input type="hidden" /&,应该说在form里面的input都应该发送过去,但是这里他只发送了四个。
既然postdata只有那么四个参数,那我们就姑且只用那个四个东西好了。
所以我们用HttpClient构造请求的时候,就应该将这四个参数的给附带进去,部分代码如下:
// 将要发送的数据封包
List&NameValuePair& params = new ArrayList&NameValuePair&();
params.add(new BasicNameValuePair("email", this.email));
params.add(new BasicNameValuePair("password", this.password));
params.add(new BasicNameValuePair("origURL", origURL));
params.add(new BasicNameValuePair("domain", domain));
接下来我们来完整登陆一次:
当输入正确的用户名密码,点击登陆,我们又获得什么样的东西呢?参见如下:
返回的内容意思大概是 地址转变了要进行跳转,而且返回的相应头是 302,文件修改了。再看一下 返回的消息头:
有一个Location,应该是要我们跳转的地址。这样我们应该可以访问人人网的任意连接资源了。
登录过程的完整代码(包含读嗅探指定资源的链接):
import java.io.IOE
import java.io.UnsupportedEncodingE
import java.util.ArrayL
import java.util.L
import org.apache.http.HttpR
import org.apache.http.NameValueP
import org.apache.http.client.ClientProtocolE
import org.apache.http.client.ResponseH
import org.apache.http.client.entity.UrlEncodedFormE
import org.apache.http.client.methods.HttpG
import org.apache.http.client.methods.HttpP
import org.apache.http.impl.client.BasicResponseH
import org.apache.http.impl.client.DefaultHttpC
import org.apache.http.message.BasicNameValueP
import org.apache.http.protocol.HTTP;
* Author : Saitkey & lei_ &
public class RenRenNotify {
private static HttpR
private static DefaultHttpClient httpC
public RenRenNotify(String userName, String password) {
this.httpClient = new DefaultHttpClient();
String loginForm = "/PLogin.do";
String origURL = "/Home.do";
String domain = "";
// 在首页表单上是隐藏的 抓包后分析,并没有发送到服务器
// String autoLogin = "true";
// 构造一个POST请求,利用Httclient提供的包
HttpPost httpPost = new HttpPost(loginForm);
// 将要发送的数据封包
List&NameValuePair& params = new ArrayList&NameValuePair&();
params.add(new BasicNameValuePair("email", userName));
params.add(new BasicNameValuePair("password", password));
params.add(new BasicNameValuePair("origURL", origURL));
params.add(new BasicNameValuePair("domain", domain));
// 封包添加到Post请求
httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
// 将 get 和post 方法包含到一个函数里面去,这里就是登陆过程了。
response = postMethod(httpPost);
* 有跳转 System.out.println(response.getStatusLine());//返回302
* Header[]headers=response.getAllHeaders(); for (int i = 0; i &
* headers. i++) { Header header = headers[i];
* System.out.println(header.getName()+": "+header.getValue()); }
// 读取跳转的地址
// String redirectUrl = response.getFirstHeader("Location").getValue();
// 查看一下跳转过后,都出现哪些内容.
// response=getMethod(redirectUrl);//函数见后面
// System.out.println(response.getStatusLine()); // HTTP/1.1 200 OK
// 读取一下主页都有什么内容 已经登陆进去
// System.out.println(readHtml("/home"));
// 嗅探指定页面的代码
public String notify(String url) {
HttpGet get = new HttpGet(url);
ResponseHandler&String& responseHandler = new BasicResponseHandler();
String txt =
txt = httpClient.execute(get, responseHandler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
get.abort();
// 用post方法向服务器请求 并获得响应,因为post方法要封装参数,因此在函数外部封装好传参
public HttpResponse postMethod(HttpPost post) {
HttpResponse resp =
resp = httpClient.execute(post);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.abort();
// 用get方法向服务器请求 并获得响应
public HttpResponse getMethod(String url) {
HttpGet get = new HttpGet(url);
HttpResponse resp =
resp = httpClient.execute(get);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
get.abort();
public static void main(String[] args) {
RenRenNotify notify = new RenRenNotify("[你的用户名]",
"[你的密码]");
System.out.println(notify
.notify("/home"));
好了,现在登录了。我们去修改自己的教育信息吧,首先自然是进入相应的页面:
当我们进入了修改教育信息的时候,我们发现HttpAnalyzer里面多了如下内容:
注意红色的内容。这里应该是所有高校的信息。体积也达到了402kb,看一下里面的内容:
这个里面有个奇怪的东西:\u4e2d\u56fd 这个是 “中国”的意思,经过转码了。用JavaScript 直接 alert('u4e2d\u56fd '),就明了了。
对于一长串的字符,可以用下面的代码进行回来(code是源):
StringBuffer sb = new StringBuffer(code);
while ((pos = sb.indexOf("\\u")) & -1) {
String tmp = sb.substring(pos, pos + 6);
sb.replace(pos, pos + 6, Character.toString((char) Integer
.parseInt(tmp.substring(2), 16)));
code = sb.toString();
接下来,我们选择一个高校看看,HttpAnalyzer里面出现如下的信息:
再来一下:
所以通过上面两次抓取,我们应该得出一个例子,那就是:我们选择好了一个大学,就会相应的得出他的ID,然后这时候会想服务器发送一个请求查询:/GetDep.do?id=13003 ,其中id后面的便是高校的代号了。然后返回的是一串html代码,如下:
这里同样是奇怪的一串数字,这种也是Unicode,不过是十进制的,而且在编码的前后分别加上“&#”和“;”就可以形成Html实体字符,可以在网页上直接显示。
对于以上的代码,我们也参照上面写一个转换的代码:如下:
StringBuffer sb=new StringBuffer(code);
while ((pos=sb.indexOf("&#"))&-1) {
String tmp=sb.substring(pos+2, pos+7);
sb.replace(pos, pos+8, Character.toString((char)Integer.parseInt(tmp,10)));
code=sb.toString();
写到这里,我们的工作也做了一大半了。于是乎,我这里不得不跟大家陈清一个事实,获得
/a13819/allunivlist.js
/GetDep.do?id=13003
的页面代码,人人网是没有设置 session的权限认证的。直接可以读不信你可以点击上面的两个地址,你就发现,原来可以直接读取的。
也就是说。我们可以另辟路径,不用通过HttpClient去登陆一下在取得数据,这一点很不好意思。我刚开始没有意识到。不过,这里你也还是学会了一种登陆一个服务器的办法,说不定以后你会用到呢。
好了,下面我们开始另一种方法。
首先,我们对获取/a13819/allunivlist.js的数据进行分析一下:
var allUnivList = [{"id":"00","univs":"","name":"\u4e2d\u56fd","provs":[{............."country_id":0,"name":"\u53f0\u6e7e"}]},{"id":"01","univs"...................
这样的数据类型。我想做过ajax的都知道是json类型的。 但是这里我要用Java的正则表达式进行解析。
首先分析数据结构:
[{国家:[{省市区[{高校S}],......}],....},....] 大概就是这样的结构 其中....表示可能有多个 同级机构。如 安徽省呵北京市, 而在北京市下有 清华大学和北京大学 是同级的。以此类推啦。
我只需要中国的的大学,所以我首先选出中国这块的数据:用到的正则表达式是:"\"provs\":(.*?)]}"
这里主要对比 在台湾省结束的时候,有]}标志,而且在前面并没有出现,而且用非贪婪模式去批判就能保证是中国的高校了。如图
取得了中国部分,接下来对中国的省市区进行解析了,同样,我们看到:
[{"id":"00",............"country_id":0,"name":"..........."},这样的结构
所以对每一个省我们可以分析到如下的正则表达式:id\":(.*?),\"univs\":(.*?),\"country_id\":0,\"name\":\"(.*?)\"}
然后对 中国这部分进行一个循环,就可以得到中国所有的省市区了,同样我们对每一个省市,要对他们包含的高校进行选择:
我们很容易就可以看到高校的 结构应该是:{"id":1001,"name":"\u6e05\u534e\u"} 类似,那么正则表达式应该是:"id\":(.*?),\"name\":\"(.*?)\"";
对于每一个高校,我们可以类似于省市那样处理,用循环匹配,就可以得到这个省市的所以高校。但是对于每一个高校。我们要还需要获得他的院系信息。前文跟大家分分析了,院系信息是通过/GetDep.do?id=xxxx来动态获取(xxx代表高校的编号),那么我们在抓取高校的时候,顺带也将他们的院系信息获取了。
写了这么多,咱直接上代码:
你也可以选择下载下面的代码。里面有一些必要的文件已经jar包,需要自己配置一下。如果不会,请留言吧,我争取重新打包再上传上来。
import java.io.F
import java.io.IOE
import java.io.PrintS
import java.util.regex.M
import java.util.regex.P
import org.apache.http.client.ClientProtocolE
import org.apache.http.client.HttpC
import org.apache.http.client.ResponseH
import org.apache.http.client.methods.HttpG
import org.apache.http.impl.client.BasicResponseH
import org.apache.http.impl.client.DefaultHttpC
* Author : Saitkey & lei_ &
public class GenerateSQL {
// 构建省的sql文件
private File province = new File("provice.sql");
// 构建高校的sql文件
private File college = new File("college.sql");
// 构建院系的sql文件
private File department = new File("department.sql");
GenerateSQL() throws ClientProtocolException, IOException {
HttpClient client = new DefaultHttpClient();
ResponseHandler&String& responseHandler = new BasicResponseHandler();
String depUrl = "/GetDep.do?id=";
String allunivs = "/a13819/allunivlist.js";
HttpGet get = new HttpGet(allunivs);
System.out.println("读取高校信息...");
StringBuffer sb = new StringBuffer(client.execute(get, responseHandler));
System.out.println("读取完成...");
// 对获取的字符串进行处理截取从"provs":到}]},{"id":"01"部分
String alluinvRegex = "\"provs\":(.*?)]}";
Pattern pattern = pile(alluinvRegex);
String chn = "";
Matcher matcher = pattern.matcher(sb.toString());
matcher.find();
chn = matcher.group(1);
// System.out.println(convertFromHex(tmp));
// 对截取的中国部分按照省市区进行匹配"id":1,"univs" ...... "country_id":0,"name":"台湾"
String regex2 = "id\":(.*?),\"univs\":(.*?),\"country_id\":0,\"name\":\"(.*?)\"}";
Pattern pattern2 = pile(regex2);
Matcher matcher2 = pattern2.matcher(chn);
StringBuilder provsBuilder = new StringBuilder();
StringBuilder colBuilder = new StringBuilder();
StringBuilder deparBuilder = new StringBuilder();
while (matcher2.find()) {
// 我们项目的sql语句,如果你们数据库不一样,稍微修改一下拉
provsBuilder.append("insert into province(PROID,PRONAME)values('"
+ matcher2.group(1) + "','"
+ convertFromHex(matcher2.group(3)) + "');\n");
System.out.println("生成-" + convertFromHex(matcher2.group(3))
+ "-数据库");
// 取得学校的ID,还有名字 "id":1001,"name":"\u6e05\u534e\u"
String colRegex = "id\":(.*?),\"name\":\"(.*?)\"";
Pattern colPattern = pile(colRegex);
Matcher colMatcher = colPattern.matcher(matcher2.group(2));
while (colMatcher.find()) {
colBuilder
.append("insert into COLLEGE(PROID,COLID,COLNAME)values('"
+ matcher2.group(1)
+ colMatcher.group(1)
+ convertFromHex(colMatcher.group(2)) + "');\n");
System.out.println("生成-" + convertFromHex(colMatcher.group(2))
+ "-数据库");
get = new HttpGet(depUrl + colMatcher.group(1));
ResponseHandler&String& depHandler = new BasicResponseHandler();
generateDepartment(client.execute(get, depHandler), colMatcher
.group(1), deparBuilder);
PrintStream ps = new PrintStream(province);
ps.print(provsBuilder.toString());
ps.close();
PrintStream ps2 = new PrintStream(college);
ps2.print(colBuilder.toString());
ps2.close();
PrintStream ps3 = new PrintStream(department);
ps3.print(deparBuilder.toString());
ps3.close();
System.err.println("\n\n\n完成数据库生成,请打开项目目录查看!");
// 这个函数用来处理行查询到的高校院系 &option
// value='中国语言文学学院'&中国语言文学学院&/option&
public void generateDepartment(String src, String colid, StringBuilder sb) {
String departRegex = "value='(.+?)'&";// 开始用这个正则表达式"value='(.*?)'&";
// 后来发现有问题,问题你自己探索吧。
Pattern pattern = pile(departRegex);
Matcher matcher = pattern.matcher(src);
while (matcher.find()) {
sb.append("insert into DEPARTMENT(COLID,DEPNAME)values('" + colid
+ "','" + convertFromDec(matcher.group(1)) + "');\n");
public static String convertDec(String src) {
return Character.toString((char) Integer.parseInt(src, 10));
public static String convertHex(String src) {
return Character
.toString((char) Integer.parseInt(src.substring(2), 16));
// 转换&#形式Unicode
private String convertFromDec(String code) {
StringBuffer sb = new StringBuffer(code);
int startP
while ((startPos = sb.indexOf("&#")) & -1) {
endPos = sb.indexOf(";");
String tmp = sb.substring(startPos + 2, endPos);
sb.replace(startPos, endPos + 1, Character.toString((char) Integer
.parseInt(tmp, 10)));
return code = sb.toString();
// 转换16进制的Unicode,
private String convertFromHex(String code) {
StringBuffer sb = new StringBuffer(code);
while ((pos = sb.indexOf("\\u")) & -1) {
String tmp = sb.substring(pos, pos + 6);
sb.replace(pos, pos + 6, Character.toString((char) Integer
.parseInt(tmp.substring(2), 16)));
return code = sb.toString();
public static void main(String[] args) throws ClientProtocolException,
IOException {
new GenerateSQL();
写到这里,基本上完成了高校数据库的抓取工作,现在只需要导入刚刚生成的sql文件就可以了。如果你想抓取其他的信息。原理也应该差不多的吧。只不过要看看他们有没有设置session 的权限认证了。如果有,那你得写一个登陆的东西获得那认证,前面也写了差不多。应该可以看懂的。感谢你花这么长的时间。
至于标题的 省 高校 院系级联,好吧, 我骗你了。只不过今天就到此了,还有Asp.net的任务。有了数据库了,咱还怕写不出来那个级联么?各位看官,如果你要什么好的级联,可以分享一下吧。
声明:抓取人人网数据仅供学习之用,不对人人网有任何恶意的行为。
satikey 写道yang02301 写道请教一下LZ:RenRen网可以用附加的程序处理Login,但是则是使用Get的方法,另附加Cookie,不知道LZ是如何处理的,请赐教。多谢!如果是GET方法,可以再后面添加参数例如?username=xxx&password=xxx大概这个样子的。你用网页登陆一下。注意浏览器的地址变化吧。等我有时间了再弄腾讯微博吧。针对
LOGON:Step1):sb = notify("/check?uin=@hdrive20&appid=&r=0.815");System.out.println("Verify Code = '" + sb.substring(18, 22)+ "'");返回验证码,如:ptui_checkVC('0','!BMF');ptui_checkVC存于login_div.js文件中。问题出现:httpcomponents-client-4.0.3是否可以执行ptui_checkVC?如何执行?Step2):得到验证码后,驶入口令,点“登录”见后,应该向browser发送get方法,如:url = "/login?u=@hdrive20&p=67E5A3B52AE29D6FC6FAFBF3&verifycode=" + sb.substring(18, 22) + "&low_login_enable=1&low_login_hour=720&aid==http%3A%2F%&ptredirect=1&h=1&from_ui=1&dumy=&fp=loginerroralert";sb = notify(url);System.out.println(sb);返回:ptuiCB('3','0','','0','您输入的密码有误,请重试。');没有关系,注意参数‘p’是用户口令经过验证码处理后的数值,本人还不知道如何得到,所以返回错误。请各位指教这个还真有意思啊。。嘿嘿。改天有时间研究一下。。最近在弄别的东西了。。
网友说,用HttpClient抓取腾讯微博的 数据很难,我想试试。哪些人报名,一起研究一下?难点在于用JavaScript写的MD5代码太恶心了(在login_div.js文件中),在ajax_Submit()中生成Password代码段如下:
if(E[A].name=="p"){
alert(E.verifycode.value);
alert(E.p.value)
F+=E.verifycode.
F=F.toUpperCase();
B+=md5(md5_3(E.p.value)+F)
E.p.value是实际口令,E.verifycode.value是返回的确认吗,4次使用MD5,function md5_3(B){
var A=new A
A=core_md5(A,B.length*chrsz);
A=core_md5(A,16*chrsz);
A=core_md5(A,16*chrsz);
return binl2hex(A);
}请哪位将MD5翻译好的Java代码贴出来共享一下,谢谢!
非常有意思,在Break in 的时候发现:当连续LOGON账户多次时,页面会出现要求输入图形认证码(显示代码在JavaScript中,当键入password时向主机请求认证码图形,修改主页HTML代码应该可以屏蔽掉),防止机器人大量Sign In,不过已经实现Java自动Logon 功能,随后发帖。请楼主继续支持如何从自动下载“高校”数据部分。现附上自动Logon到的Java代码,需要修改username和password,继续努力!
import java.io.IOE
import java.io.UnsupportedEncodingE
import java.util.ArrayL
import java.util.L
import org.apache.http.H
import org.apache.http.HttpR
import org.apache.http.NameValueP
import org.apache.http.client.ClientProtocolE
import org.apache.http.client.ResponseH
import org.apache.http.client.entity.UrlEncodedFormE
import org.apache.http.client.methods.HttpG
import org.apache.http.client.methods.HttpP
import org.apache.http.impl.client.BasicResponseH
import org.apache.http.impl.client.DefaultHttpC
import org.apache.http.message.BasicNameValueP
import org.apache.http.protocol.HTTP;
import java.security.*;
public class QQNotify {
private static HttpR
private static DefaultHttpClient httpC
public static void main(String[] args) {
String username = "your username";
String password = "your password";
QQNotify notify = new QQNotify(username, password);
if (true) {
String code = new String(notify.notify("/a13819/allunivlist.js"));
// 转换16进制的Unicode,
StringBuffer sb = new StringBuffer(code);
System.out.println(sb.toString());
while ((pos = sb.indexOf("\\u")) & -1) {
String tmp = sb.substring(pos, pos + 6);
sb.replace(pos, pos + 6, Character.toString((char) Integer.parseInt(tmp.substring(2), 16)));
code = sb.toString();
System.out.println(code);
///如果你要看下面代码的效果,你只需要 注释掉上面String code
到 System.out.println(code);
//转换&#形式Unicode
String code = new String(notify
.notify("/GetDep.do?id=13003"));
StringBuffer sb=new StringBuffer(code);
while ((pos=sb.indexOf("&#"))&-1) {
String tmp=sb.substring(pos+2, pos+7);
sb.replace(pos, pos+8, Character.toString((char)Integer.parseInt(tmp,10)));
code=sb.toString();
System.out.println(code);
public QQNotify(String userName, String password) {
this.httpClient = new DefaultHttpClient();
String url, sb, verifyC
// Step 1: get verify code
url = "/check?uin=@" + userName + "&appid=&r=0.815";
sb = notify(url);
i = sb.indexOf("'", 19);
verifyCode = sb.substring(18, i).toUpperCase();
System.out.println(sb);
System.out.println("Verify Code = '" + verifyCode + "'");
if (!false && verifyCode.length() & 4) {
System.out.println("It seem you need input graphic verify code manually.");
System.out.println("Wait a few minutes and try again.");
System.out.println("Program abort!");
// Step 2: logon
// '!UAK' -& '67E5A3B52AE29D6FC6FAFBF3'
//String str = MD5_3(password) + "!UAK";
//System.out.println("str = " + str);
//System.out.println("MD5 = " + MD5(str));
String str = MD5_3(password) + verifyC
url = "/login?u=@" +
userName + "&p=" +
MD5(str) + "&verifycode=" +
verifyCode + "&low_login_enable=1&low_login_hour=720&aid==http%3A%2F%&ptredirect=1&h=1&from_ui=1&dumy=&fp=loginerroralert";
sb = notify(url);
System.out.println(sb);
if (!true) {
response = getMethod(url);
System.out.println(response.getStatusLine());//返回302
headers = response.getAllHeaders();
for (i = 0; i & headers. i++) {
Header header = headers[i];
System.out.println(header.getName() + ": " + header.getValue());
System.out.println("-----------------------------");
if (true) {
System.out.println("Already logon to '" + userName + "' @
successfully.");
System.out.println("Next you need redirect to /setting_edu.php, and grap college data.");
System.out.println("Good luck!");
// 读取跳转的地址
// String redirectUrl = response.getFirstHeader("Location").getValue();
// 查看一下跳转过后,都出现哪些内容.
// response=getMethod(redirectUrl);//函数见后面
// System.out.println(response.getStatusLine()); // HTTP/1.1 200 OK
// 读取一下主页都有什么内容 已经登陆进去
// System.out.println(readHtml("/home"));
// 嗅探指定页面的代码
public String notify(String url) {
HttpGet get = new HttpGet(url);
ResponseHandler&String& responseHandler = new BasicResponseHandler();
String txt =
txt = httpClient.execute(get, responseHandler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
get.abort();
// 用post方法向服务器请求 并获得响应,因为post方法要封装参数,因此在函数外部封装好传参
public HttpResponse postMethod(HttpPost post) {
HttpResponse resp =
resp = httpClient.execute(post);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.abort();
// 用get方法向服务器请求 并获得响应
public HttpResponse getMethod(String url) {
HttpGet get = new HttpGet(url);
HttpResponse resp =
resp = httpClient.execute(get);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
get.abort();
private String MD5_3(String plainText) {
StringBuffer buf = new StringBuffer("");
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
// first time
byte b[] = md.digest();
// Second Time
b = md.digest(b);
// Third Time
b = md.digest(b);
for (int offset = 0; offset & b. offset++) {
i = b[offset];
if (i & 0) {
if (i & 16) {
buf.append("0");
buf.append(Integer.toHexString(i));
//System.out.println("32-bit result: " + buf.toString());//32位的加密
//System.out.println("byte b[].size: " + b.length);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return buf.toString().toUpperCase();
private String MD5(String plainText) {
StringBuffer buf = new StringBuffer("");
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
for (int offset = 0; offset & b. offset++) {
i = b[offset];
if (i & 0) {
if (i & 16) {
buf.append("0");
buf.append(Integer.toHexString(i));
//System.out.println("32-bit result: " + buf.toString());//32位的加密
//System.out.println("byte b[].size: " + b.length);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return buf.toString().toUpperCase();
已经搞定,可以自动LOGON,保存Cookies,Redirect URL,得到“高校”列表,得到“院系”列表部分还没有做,应该非常容易的啦,感谢LZ开阔思维!在发送GET得到“高校”列表时,应该注意造一个请求头,假装使用浏览器。请LZ在做一个简单的图形码验证LOGON例子,使用QQ所采用的。最后附上源码,后增加的部分还没有整理,有些乱,请多多包含。
import java.io.IOE
import java.io.UnsupportedEncodingE
import java.util.ArrayL
import java.util.L
import java.util.logging.L
import java.util.logging.L
import org.apache.http.H
import org.apache.http.HttpR
import org.apache.http.NameValueP
import org.apache.http.client.ClientProtocolE
import org.apache.http.client.ResponseH
import org.apache.http.client.entity.UrlEncodedFormE
import org.apache.http.client.methods.HttpG
import org.apache.http.client.methods.HttpP
import org.apache.http.impl.client.BasicResponseH
import org.apache.http.impl.client.DefaultHttpC
import org.apache.http.message.BasicNameValueP
import org.apache.http.protocol.HTTP;
import java.security.*;
import java.util.HashM
import java.util.I
import java.util.M
import java.util.S
import java.util.regex.M
import java.util.regex.P
import org.apache.http.cookie.C
public class QQNotify {
private static HttpR
private static DefaultHttpClient httpC
private static Map&String, String& cookies = new HashMap&String, String&();
public static void main(String[] args) {
String username = "your username";
String password = "your password";
QQNotify notify = new QQNotify(username, password);
if (true) {
String code = new String(notify.notify("/a13819/allunivlist.js"));
// 转换16进制的Unicode,
StringBuffer sb = new StringBuffer(code);
System.out.println(sb.toString());
while ((pos = sb.indexOf("\\u")) & -1) {
String tmp = sb.substring(pos, pos + 6);
sb.replace(pos, pos + 6, Character.toString((char) Integer.parseInt(tmp.substring(2), 16)));
code = sb.toString();
System.out.println(code);
///如果你要看下面代码的效果,你只需要 注释掉上面String code
到 System.out.println(code);
//转换&#形式Unicode
String code = new String(notify
.notify("/GetDep.do?id=13003"));
StringBuffer sb=new StringBuffer(code);
while ((pos=sb.indexOf("&#"))&-1) {
String tmp=sb.substring(pos+2, pos+7);
sb.replace(pos, pos+8, Character.toString((char)Integer.parseInt(tmp,10)));
code=sb.toString();
System.out.println(code);
public QQNotify(String userName, String password) {
this.httpClient = new DefaultHttpClient();
String url, sb, verifyC
cookies.clear();
// Step 1: get verify code
url = "/check?uin=@" + userName + "&appid=&r=0.815";
sb = notify(url);
SaveCookies(httpClient.getCookieStore().getCookies());
i = sb.indexOf("'", 19);
verifyCode = sb.substring(18, i).toUpperCase();
System.out.println(sb);
System.out.println("Verify Code = '" + verifyCode + "'");
if (!false && verifyCode.length() & 4) {
System.out.println("It seem you need input graphic verify code manually.");
System.out.println("Wait a few minutes and try again.");
System.out.println("Program abort!");
// Step 2: logon
// '!UAK' -& '67E5A3B52AE29D6FC6FAFBF3'
//String str = MD5_3(password) + "!UAK";
//System.out.println("str = " + str);
//System.out.println("MD5 = " + MD5(str));
String str = MD5_3(password) + verifyC
url = "/login?u=@"
+ userName + "&p="
+ MD5(str) + "&verifycode="
+ verifyCode + "&low_login_enable=1&low_login_hour=720&aid==http%3A%2F%&ptredirect=1&h=1&from_ui=1&dumy=&fp=loginerroralert";
sb = notify(url);
System.out.println(sb);
SaveCookies(httpClient.getCookieStore().getCookies());
PrintCookies();
ptuiCB('0','0','','1','登录成功!');
-------- Cookies begin ---------
Exception in thread "main" java.lang.NullPointerException
0 : [ptvfsession] = 'a56b05373bffaf65643dbe875a1c9c91ddd8b087b3f8fd21670efcc430d111b63fa41274f'
1 : [ptcz] = '06aa93cefb0fec33c298f13fecadb6adb11a5e56115'
2 : [skey] = '@na9wdcELd'
3 : [pt2gguin] = 'o'
4 : [lskey] = 'ac49b4a67ea43dde8d846c27cd4a57ddadc6c9f972099'
5 : [luin] = 'o'
6 : [uin] = 'o'
7 : [ptuserinfo] = '3230'
8 : [ptisp] = ''
-------- Cookies end ---------
-------- Cookies begin ---------
0 : [ptvfsession] = 'cbebb4c13f69aaca9dabea361c77de60d0fb02bddc5abd651e4bbd99faebef2bb'
1 : [ptcz] = 'bf9bd2ac71844eaefbdcb0dd175da7f3a'
2 : [skey] = '@na9wdcELd'
3 : [pt2gguin] = 'o'
4 : [lskey] = 'cf86f252e61d9e8f07aa2cf01a2863caaffdb4d9e1aa64fccd'
5 : [luin] = 'o'
6 : [uin] = 'o'
7 : [ptuserinfo] = '3230'
8 : [ptisp] = ''
-------- Cookies end ---------
if (true) {
// Now get country city list
// sample get data
GET /asyn/schoolist.php?type=4&key=%E4%B8%AD%E5%9B%BD_%E5%8C%97%E4%BA%AC&letter=& HTTP/1.1
Accept: *//*
Accept-Language: en-us
Referer: /setting_edu.php
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 ( MSIE 7.0; Windows NT 6.1; Trident/4.0; QQPinyin 730; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Connection: Keep-Alive
Cookie: ptui_loginuin2=hdrive20; mb_reg_from=8; pgv_pvid=; pgv_flv=10.0; pgv_r_cookie=71; pt2gguin=o; ptcz=3ac05d30f3e337e94f4fed3bb8f7d86b7a2e34e548d; o_cookie=; luin=o; lskey=b1dff0aad30b3b96d163ec6da83a219311bcb2ffe3f2; pgv_info=ssid=s; verifysession=hbd8e1f0f07df6a4bbd1eace18b6c; ptisp=; uin=o; skey=@na9wdcELd
tui_loginuin2=hdrive20;
mb_reg_from=8;
pgv_pvid=;
pgv_flv=10.0;
pgv_r_cookie=71;
pt2gguin=o;
ptcz=3ac05d30f3e337e94f4fed3bb8f7d86b7a2e34e548d;
o_cookie=;
lskey=b1dff0aad30b3b96d163ec6da83a219311bcb2ffe3f2;
pgv_info=ssid=s;
verifysession=hbd8e1f0f07df6a4bbd1eace18b6c;
skey=@na9wdcELd
//String redirectUrl = "/setting_edu.php";
///asyn/schoolist.php?type=4&key=%E4%B8%AD%E5%9B%BD_%E5%8C%97%E4%BA%AC&letter=&
//中国_北京
String redirectUrl = "/asyn/schoolist.php?type=4&key=%E4%B8%AD%E5%9B%BD_%E5%8C%97%E4%BA%AC&letter=&";
//String redirectUrl = "/asyn/schoolist.php?type=4&key=%E7%BE%8E%E5%9B%BD&letter=&";
HttpGet get = new HttpGet(redirectUrl);
get.setHeader("Accept", "*/*");
get.setHeader("Accept-Language", "en-us");
get.setHeader("Referer", "/setting_edu.php");
get.setHeader("User-Agent", "gzip, deflate");
get.setHeader("Accept-Language", "Mozilla/4.0 ( MSIE 7.0; Windows NT 6.1; Trident/4.0; QQPinyin 730; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)");
get.setHeader("Host", "");
get.setHeader("Connection", "Keep-Alive");
sb = httpClient.execute(get, new BasicResponseHandler());
} catch (IOException ex) {
Logger.getLogger(QQNotify.class.getName()).log(Level.SEVERE, null, ex);
//sb = notify(redirectUrl);
System.out.println(sb);
String regex2 = "title=\"(.*?)\"&";
Pattern pattern2 = pile(regex2);
Matcher matcher2 = pattern2.matcher(sb);
while (matcher2.find()) {
System.out.println(matcher2.group(1));
System.out.println("Already logon to '" + userName + "' @
successfully.");
System.out.println("Next you need redirect to /setting_edu.php do grap colleg data.");
System.out.println("Good luck!");
// 读取跳转的地址
// String redirectUrl = response.getFirstHeader("Location").getValue();
// 查看一下跳转过后,都出现哪些内容.
// response=getMethod(redirectUrl);//函数见后面
// System.out.println(response.getStatusLine()); // HTTP/1.1 200 OK
// 读取一下主页都有什么内容 已经登陆进去
// System.out.println(readHtml("/home"));
// 嗅探指定页面的代码
public String notify(String url) {
HttpGet get = new HttpGet(url);
//get.setHeader("User-Agent", "Mozilla/4.0 ( MSIE 7.0; Windows NT 6.1; Trident/4.0; QQPinyin 730; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)");
ResponseHandler&String& responseHandler = new BasicResponseHandler();
String txt =
txt = httpClient.execute(get, responseHandler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
get.abort();
// 用post方法向服务器请求 并获得响应,因为post方法要封装参数,因此在函数外部封装好传参
public HttpResponse postMethod(HttpPost post) {
HttpResponse resp =
resp = httpClient.execute(post);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.abort();
// 用get方法向服务器请求 并获得响应
public HttpResponse getMethod(String url) {
HttpGet get = new HttpGet(url);
HttpResponse resp =
resp = httpClient.execute(get);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
get.abort();
private String MD5_3(String plainText) {
StringBuffer buf = new StringBuffer("");
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
// first time
byte b[] = md.digest();
// Second Time
b = md.digest(b);
// Third Time
b = md.digest(b);
for (int offset = 0; offset & b. offset++) {
i = b[offset];
if (i & 0) {
if (i & 16) {
buf.append("0");
buf.append(Integer.toHexString(i));
//System.out.println("32-bit result: " + buf.toString());//32位的加密
//System.out.println("byte b[].size: " + b.length);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return buf.toString().toUpperCase();
private String MD5(String plainText) {
StringBuffer buf = new StringBuffer("");
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
for (int offset = 0; offset & b. offset++) {
i = b[offset];
if (i & 0) {
if (i & 16) {
buf.append("0");
buf.append(Integer.toHexString(i));
//System.out.println("32-bit result: " + buf.toString());//32位的加密
//System.out.println("byte b[].size: " + b.length);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return buf.toString().toUpperCase();
private void SaveCookies(List&Cookie& cs) {
if (cs.isEmpty()) {
System.out.println("None");
for (int i = 0; i & cs.size(); i++) {
cookies.put(cs.get(i).getName(), cs.get(i).getValue());
private void PrintCookies() {
int i = 0;
//Get Map in Set interface to get key and value
Set s = cookies.entrySet();
//Move next key and value of Map by iterator
Iterator it = s.iterator();
System.out.println("-------- Cookies begin ---------");
while (it.hasNext()) {
// key=value separator this by Map.Entry to get key and value
Map.Entry m = (Map.Entry) it.next();
System.out.println(" " + i++ + " : [" + m.getKey() + "] = '" + m.getValue() + "'");
System.out.println("-------- Cookies end ---------");
//Get Canada School List
///asyn/schoolist.php?type=4&key=%E5%8A%A0%E6%8B%BF%E5%A4%A7&letter=&
厉害,获取高校院系的那部分就很简单了。恩。基本上就是get post请求了。
请高手添加一段代码,从/www/mb/js/mi.City_100831.js导入JSON源数据到Java变量中。拜托!我不熟悉 Json数据到Java变量。上次准备弄,因为其他事情耽搁了。
我已经将它搞定。输出得那叫一个爽。
世界所有国家:
===========
&没有定义&
巴勒克埃西尔
巴伊布尔特
迪亚巴克尔
埃斯基谢希尔
埃尔祖鲁姆
加济安泰普
居米什哈内
伊斯帕尔塔
伊斯坦布尔
卡赫拉曼马拉什
卡斯塔莫努
柯克拉雷利
克尔谢希尔
克勒克卡莱
(超长无法显示)
我已经将它搞定。输出得那叫一个爽。
中国所有城市:
===========
青龙满族自治县
鹰手营子矿区
丰宁满族自治县
宽城满族自治县
围场满族蒙古族自治县
上传中国和世界大学院校列表(数据取自qq微薄)上传中国大学院校所含院系列表(数据取自qq微薄)呵呵。那我做第一个下载的观众了。
yang02301 写道上传中国和世界大学院校列表(数据取自qq微薄)上传中国大学院校所含院系列表(数据取自qq微薄)呵呵。那我做第一个下载的观众了。不知道大家还有什么资料需要从网上搜刮的,先提出来,看看我能否做到.
(本文来自互联网,不代表搜站(/)的观点和立场)本站所有内容来自互联网,若本站收录的信息无意侵犯了贵司版权,请给我们来信(),我们会及时处理和回复,谢谢编辑推荐最近更新}

我要回帖

更多关于 college data 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信