网络爬虫入门(二)模拟提交以及HttpClient修正
模拟提交就是说我们不自己登陆到客户端,仅仅靠发送请求就模拟了客户端的操作,在现实使用的时候经常用来接收一些需要登录才能获取到的数据,来模拟表单的提交,所以很多时候也被称作虚拟登录,这次的例子是我自己为学校实验室开发的官方网站的纳新报名系统,设置有一个管理员,管理员通过登录就可以查看报名人的信息,做一个虚拟登录来获取到报名信息页面,因为如果没有登录直接到达这个页面,页面是不给访问的,具体技术我开发的时候用到了session,就不详细描述了。
那么获取数据的条件为:(报名信息URL为...省略\FreshTable.html,登录页面为...省略\login.html)
1.必须登录
2.为POST请求方式
首先是先直接输入报名信息的页面我们会看到页面直接跳到了登录页面。如果直接没有登录的时候抓取网页的时候我们可以看到的现象是(URL:...省略\FreshTable.html):
1 <div class="msg2 fl">欢迎管理员登录</div> 2 <div class="hline fr"> 3 </div> 4 </div> 5 <div class="inputer"> 6 <form action="FreshTable.html" method="post"> 7 <input class="inputext" type="text" name="UserName" id="UserName" placeholder="用户名" onkeydown="if(event.keyCode==13) event.keyCode=9"> 8 <input class="inputext" type="password" name="Password" id="Password" placeholder="密码"> 9 <input type="submit" id="submitbtn" value="登录"/>
现在开始我们的主题。
经过研究发现,昨天的HttpClient的包官方已经不用了,现在属于遗留的包,Maven都找不到昨天的包,所以今天重新换了新的包,之前的common下的HttpClient包,这次使用的是
org.apache.http.impl.client.HttpClients;
这个包。
这个包在Maven中配置是:
1 <dependency> 2 <groupId>org.apache.httpcomponents</groupId> 3 <artifactId>httpclient</artifactId> 4 <version>4.5.1</version> 5 </dependency>
这里我选用了4.5.1的包,也可以选择其他版本。
现在进行编码,今天这个包的操作和之前有一定的区别,所以代码就改了
1 CloseableHttpClient httpClient= HttpClients.createDefault(); 2 HttpPost post=new HttpPost("××××××××/FreshTable.html"); 3 try { 4 CloseableHttpResponse response=httpClient.execute(post); 5 System.out.println(EntityUtils.toString(response.getEntity())); 6 } catch (IOException e) { 7 e.printStackTrace(); 8 } 9 10 }
以上代码的功能为输出这个URL的内容然而并不是我们想要的内容:获得的HTML代码为之前开始的HTML代码。这是就需要一个虚拟登录了。
首先我们要知道表单的代码,这里表单的代码为:
1 <input class="inputext" type="text" name="UserName" id="UserName" placeholder="用户名" onkeydown="if(event.keyCode==13) event.keyCode=9"> 2 <input class="inputext" type="password" name="Password" id="Password" placeholder="密码"> 3 <input type="submit" id="submitbtn" value="登录"/>
我们可以看到name的值分别为UserName和password,分别对应这用户名和密码,所以我们就可以通过这个来登录。
先解释几个类和方法:
BasicNameValuePair
用来写入Name值和对应的value值
UrlEncodedFormEntity
这个将那些name和value写到实例中,构造方法对应的两个是BasicNameValuePair的数据和字符编码。之后在用post来发送请求。
整体代码为:
1 public class TestSp01 { 2 public static void main(String[] args){ 3 CloseableHttpClient httpClient= HttpClients.createDefault(); 4 HttpPost post=new HttpPost("http://×××××××××/FreshTable.html"); 5 List<NameValuePair> formparams=new ArrayList<NameValuePair>(); 6 formparams.add(new BasicNameValuePair("UserName","××××××")); 7 formparams.add(new BasicNameValuePair("Password","××××××")); 8 UrlEncodedFormEntity entity=new UrlEncodedFormEntity(formparams, Consts.UTF_8); 9 post.setEntity(entity); 10 try { 11 CloseableHttpResponse response=httpClient.execute(post); 12 System.out.println(EntityUtils.toString(response.getEntity())); 13 } catch (IOException e) { 14 e.printStackTrace(); 15 } 16 17 } 18 }
以上代码运行就执行了使用post方式登录,那么这时获取到的数据也就成为了:
1 <tr> 2 <td>×××××</td> 3 <td>×××××</td> 4 <td>1×××××××××37</td> 5 <td>光电××××</td> 6 <td>0</td> 7 <td>10××××××80</td> 8 <td>104××××××@××.com</td> 9 </tr> 10 11 <tr> 12 …… 13 </tr>
完成了一次模拟提交。
=========================================