抓取ajax动态网页java(谷歌的network模拟请求和实现原理登录之后返回的网页源码)

优采云 发布时间: 2021-09-11 10:15

  抓取ajax动态网页java(谷歌的network模拟请求和实现原理登录之后返回的网页源码)

  一、实现原理

  登录后,进行数据分析,准确抓取数据。

  根据上一篇文章的代码,我们不仅获得了cookies,还获得了登录后返回的网页源代码。这时候有以下几种情况:

  (1)如果我们需要的数据在登陆后返回的源码中,那么我们可以直接通过Jsoup解析源码,然后利用Jsoup的selector函数过滤掉我们需要的信息;<//p

p(2)如果需要通过请求源码中的链接获取需要的数据,那么我们会先解析源码找出url,然后带上cookie来模拟对这个url的请求。/p

p(3)如果源代码中根本没有我们需要的数据,那么我们可以忽略源代码。我们看浏览器,打开谷歌的网络,搜索分析所有的URL请求和响应结果,在一般接下来总能找到那个url(一般这个url是固定的url,参数可能不同),返回的数据就是我们期望的,然后我们模拟请求这个url,我们就可以用cookies请求了./p

p第一次写模拟登录的时候,总觉得数据必须在网页的源码中获取,所以当一个网页是一堆js组成的时候,傻眼了。那么我希望得到渲染网页的源码,你可以试试selenium,以后学习使用。/p

p二、详细实现过程/p

pprespan style="color: rgba(0, 0, 255, 1)"package/spanspan style="color: rgba(0, 0, 0, 1)" debug;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" java.util.HashMap;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" java.util.List;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" java.util.Map;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.Connection;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.Connection.Method;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.Connection.Response;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.Jsoup;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.nodes.Document;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.nodes.Element;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" java.io.IOException;

/spanspan style="color: rgba(0, 0, 255, 1)"import/spanspan style="color: rgba(0, 0, 0, 1)" org.jsoup.select.Elements;

/spanspan style="color: rgba(0, 0, 255, 1)"public/span span style="color: rgba(0, 0, 255, 1)"class/spanspan style="color: rgba(0, 0, 0, 1)" test {

/spanspan style="color: rgba(0, 0, 255, 1)"public/span span style="color: rgba(0, 0, 255, 1)"static/span String LOGIN_URL = "http://authserver.tjut.edu.cn/authserver/login"span style="color: rgba(0, 0, 0, 1)";

/spanspan style="color: rgba(0, 0, 255, 1)"public/span span style="color: rgba(0, 0, 255, 1)"static/span String USER_AGENT = "User-Agent"span style="color: rgba(0, 0, 0, 1)";

/spanspan style="color: rgba(0, 0, 255, 1)"public/span span style="color: rgba(0, 0, 255, 1)"static/span String USER_AGENT_VALUE = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"span style="color: rgba(0, 0, 0, 1)";

/spanspan style="color: rgba(0, 0, 255, 1)"public/span span style="color: rgba(0, 0, 255, 1)"static/span span style="color: rgba(0, 0, 255, 1)"void/span main(String[] args) span style="color: rgba(0, 0, 255, 1)"throws/spanspan style="color: rgba(0, 0, 0, 1)" Exception {

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 模拟登陆github的用户名和密码

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" String url = "/spanspan style="color: rgba(0, 128, 0, 1); text-decoration: underline"http://ehall.tjut.edu.cn/publicapp/sys/zxzxapp/index.do/spanspan style="color: rgba(0, 128, 0, 1)"#/consultingList";/span

String url ="http://ehall.tjut.edu.cn/publicapp/sys/zxzxapp/index.do"span style="color: rgba(0, 0, 0, 1)";

get_html_num(url);

}

/spanspan style="color: rgba(0, 128, 0, 1)"/**/spanspan style="color: rgba(0, 128, 0, 1)"

* /spanspan style="color: rgba(128, 128, 128, 1)"@param/spanspan style="color: rgba(0, 128, 0, 1)" userName 用户名

* /spanspan style="color: rgba(128, 128, 128, 1)"@param/spanspan style="color: rgba(0, 128, 0, 1)" pwd 密码

* /spanspan style="color: rgba(128, 128, 128, 1)"@throws/spanspan style="color: rgba(0, 128, 0, 1)" Exception

/spanspan style="color: rgba(0, 128, 0, 1)"*//span

span style="color: rgba(0, 0, 255, 1)"public/span span style="color: rgba(0, 0, 255, 1)"static/span MapString, String simulateLogin(String userName, String pwd) span style="color: rgba(0, 0, 255, 1)"throws/spanspan style="color: rgba(0, 0, 0, 1)" Exception {

/spanspan style="color: rgba(0, 128, 0, 1)"/*/spanspan style="color: rgba(0, 128, 0, 1)"

* 第一次请求 grab login form page first 获取登陆提交的表单信息,及修改其提交data数据(login,password)

/spanspan style="color: rgba(0, 128, 0, 1)"*//span

span style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" get the response, which we will post to the action URL(rs.cookies())/span

Connection con = Jsoup.connect(LOGIN_URL); span style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 获取connection/span

con.header(USER_AGENT, USER_AGENT_VALUE); span style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 配置模拟浏览器/span

Response rs = con.execute(); span style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 获取响应/span

Document d1 = Jsoup.parse(rs.body()); span style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 通过Jsoup将返回信息转换为Dom树/span

ListElement eleList = d1.select("#casLoginForm"); span style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 获取提交form表单,可以通过查看页面源码代码得知

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 获取cooking和表单属性

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" lets make data map containing all the parameters and its values found in the

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" form/span

MapString, String datas = span style="color: rgba(0, 0, 255, 1)"new/span HashMapspan style="color: rgba(0, 0, 0, 1)"();

/spanspan style="color: rgba(0, 0, 255, 1)"for/span (Element e : eleList.get(0span style="color: rgba(0, 0, 0, 1)").getAllElements()) {

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 注意问题2:设置用户名 注意equals(这个username和password也是要去自己的登录界面input里找name值)/span

span style="color: rgba(0, 0, 255, 1)"if/span (e.attr("name").equals("username"span style="color: rgba(0, 0, 0, 1)")) {

e.attr(/span"value"span style="color: rgba(0, 0, 0, 1)", userName);

}

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 设置用户密码/span

span style="color: rgba(0, 0, 255, 1)"if/span (e.attr("name").equals("password"span style="color: rgba(0, 0, 0, 1)")) {

e.attr(/span"value"span style="color: rgba(0, 0, 0, 1)", pwd);

}

/spanspan style="color: rgba(0, 128, 0, 1)"///spanspan style="color: rgba(0, 128, 0, 1)" 排除空值表单属性/span

span style="color: rgba(0, 0, 255, 1)"if/span (e.attr("name").length() > 0) {

datas.put(e.attr("name"), e.attr("value"));

}

}

/*

* 第二次请求,以post方式提交表单数据以及cookie信息

*/

Connection con2 = Jsoup.connect(

"http://authserver.tjut.edu.cn/authserver/login");

con2.header(USER_AGENT, USER_AGENT_VALUE);

// 设置cookie和post上面的map数据

Response login = con2.ignoreContentType(true).followRedirects(true).method(Method.POST).data(datas)

.cookies(rs.cookies()).execute();

//报错Exception in thread "main" org.jsoup.HttpStatusException: HTTP error fetching URL. Status=500,

// 报错原因:见上边注意问题2

// 打印,登陆成功后的信息

//System.out.println(login.body());

// 登陆成功后的cookie信息,可以保存到本地,以后登陆时,只需一次登陆即可

Map map = login.cookies();

// for (String s : map.keySet()) {

// System.out.println(s + " : " + map.get(s));

// }

return map;

}

// 实现切割某两个字之间的字符串

public static String findstr(String str1, String strstrat, String strend) {

String finalstr = new String();

int strStartIndex = str1.indexOf(strstrat);

int strEndIndex = str1.indexOf(strend);

finalstr = str1.substring(strStartIndex, strEndIndex).substring(strstrat.length());

return finalstr;

}

// 第一个,完整爬虫爬下来内容

public static void get_html_num(String url) throws Exception {

try {

Map cookies=simulateLogin("203128301", "密码保护");

// Document doc = Jsoup.connect(url).get();

Document doc = Jsoup.connect(url).cookies(cookies).post();

// 得到html中id为content下的所有内容

Element ele = doc.getElementById("consultingListDetail");

// 分离出下面的具体内容

// Elements tag = ele.getElementsByTag("td");

// for (Element e : tag) {

// String title = e.getElementsByTag("td").text();

// String Totals = findstr(title, "共", "条");

// System.out.println(Totals);

System.out.println(doc);

// }

} catch (IOException e) {

e.printStackTrace();

}

}

}

  三、当前问题

  目标界面的内容是通过AJAX动态加载的,无法使用jsoup获取目标信息。

  什么是 AJAX

  AJAX(Asynchronouse JavaScript And XML)异步 JavaScript 和 XML。通过在后台与服务器交换少量数据,Ajax 可以使网页异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。如果内容需要更新,传统网页(不使用 Ajax)必须重新加载整个网页。因为传统的数据传输格式是XML语法。所以它被称为 AJAX。其实现在数据交互基本都是用JSON。使用AJAX加载的数据,即使使用JS将数据渲染到浏览器中,在右键->查看网页源代码中仍然看不到通过ajax加载的数据,只能看到使用这个url加载的html代码。

  解决方案:

  ①直接分析AJAX调用的接口。然后通过代码请求这个接口。

  ②使用selenium模拟点击解决问题。

  实现过程参考下两篇文章:

  java爬虫(五)使用selenium模拟点击获取动态页面内容

  java爬虫(六)analyze AJAX接口获取网页动态内容

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线