近期在作公司一个web项目。要求在咱们的系统上,能够显示其它站点上的数据。html
刚開始接到这个任务时,还在想。简单的很是。直接用UrlConection直接进入该网页,而后获取该网页的html,取到想要的数据。返回给咱们的系统的前台页面,打印出来。java
还想到了设计模式,以便从此扩展至能够查看多个网页。web
可是。思路是简单的,真正作的时候却乱了思路。。。apache
这个网页还要登陆。。。设计模式
因而在网上找模拟登陆的实例。查了一下,思路是这种:浏览器
a)先把账号与password加如到请求中。cookie
而后进行登陆网络
b)在登陆以后。获取登陆的cookiesession
c)依据获取的cookie,再訪问你想要的去的地址。app
与以前的差异是。在输出流中。添加帐户名和password,代码例如如下
StringBuffer sb = new StringBuffer(); sb.append("email="+usr); sb.append("&password="+pwd); OutputStream os = connection.getOutputStream(); os.write(sb.toString());但是运行的时候,返回的html倒是没有登陆的页面。
发现仍是由于登陆的时候出现错误,cookie也没有收到。
那么问题就来了,登陆网页究竟哪家强?
这个email和password这两个參数,我用的是html账号和密码元素的id。这两个參数名对吗?这两个还要其它值吗?这个方式究竟对不正确?
而后又在网上继续探索。。。
因而出现了如下的代码:
package com.task; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; public class RenRen { // The configuration items private static String userName = "你的账号"; private static String password = "你的密码"; private static String redirectURL = "http://jk.coolchuan.com/report/total-downloads"; // Don't change the following URL private static String renRenLoginURL = "http://www.coolchuan.com/sign_in"; // The HttpClient is used in one session private HttpResponse response; private DefaultHttpClient httpclient = new DefaultHttpClient(); private boolean login() { HttpPost httpost = new HttpPost(renRenLoginURL); // All the parameters post to the web site List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("redirect_uri", "")); nvps.add(new BasicNameValuePair("user[remember_me]", "1")); nvps.add(new BasicNameValuePair("user[email]", userName)); nvps.add(new BasicNameValuePair("user[password]", password)); try { httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); response = httpclient.execute(httpost); CookieStore cookieStore = httpclient.getCookieStore(); List<Cookie> cookies = cookieStore.getCookies(); for(Cookie c : cookies) { System.out.println("#############"+c); } } catch (Exception e) { e.printStackTrace(); return false; } finally { httpost.abort(); } return true; } private String getRedirectLocation() { Header[] headers = response.getAllHeaders(); for(int i = 0; i < headers.length; i++) { System.out.println(headers[i]); } Header locationHeader = response.getFirstHeader("Location"); if (locationHeader == null) { return null; } return locationHeader.getValue(); } private String getText(String redirectLocation) { HttpGet httpget = new HttpGet(redirectLocation); // Create a response handler ResponseHandler<String> responseHandler = new BasicResponseHandler(); String responseBody = ""; try { responseBody = httpclient.execute(httpget, responseHandler); } catch (Exception e) { e.printStackTrace(); responseBody = null; } finally { httpget.abort(); httpclient.getConnectionManager().shutdown(); } return responseBody; } public void printText() { if (login()) { // String redirectLocation = getRedirectLocation(); if (redirectURL != null) { System.out.println(getText(redirectURL)); } } } public static void main(String[] args) { RenRen renRen = new RenRen(); renRen.printText(); } }
第27行,就是登陆的url,第24行是重定向的url,也就是登陆后我想要跳转到的url
那么问题又来了。第37行到第40行,账号,password为何要这样写?怎么多出了个redirect_uri和user[remember_me]?
作过web的同窗都清楚。在登陆页面提交请求的时候,事实上就是提交一个表单。需要在请求中增长參数,后台在接的时候。依据接到的參数。进行推断。接到的參数是否正确,进而返回前台是否登陆成功。
假设成功,则进入成功跳转页面,假设不成功。则仍是登陆页面,提示信息,”登陆失败“。
请求的參数名,是需要经过工具查看的。
我推荐用firefox的firebug。
Firebug的网络监视器相同是功能强大的,能够查看HttpRequests请求的http头等等。如下给出详细查看过程:
一、打开火狐浏览器,按F12打开firebug,打开网络选项卡(假设是第一次打开,则需要点击“启动”button),点击”保持“
二、地址栏输入网页url,这里输入的是 http://www.coolchuan.com/sign_in。再点击“清除”。把多余的网络请求清掉
三、输入账号password。而后登陆,查看网络状况,找到Post的请求,例如如下图:
哈哈,想要的參数来了。
这个參数就是模拟登陆的关键点。看来最初的设想都是错误的。
这里也出来了一个很是严重的站点的漏洞。请同窗们自行寻找吧,嘿嘿。