htmlunit 模拟登录 数字验证码
使用htmlunit的好处有两点,相比httpclient,htmlunit是对浏览器的模拟,比如你定位一个按钮,就可以执行click()方法,此外不需要象在httpclient中一样编写复杂的代码,如一堆request header还有一大堆请求参数,你只需要填写用户名,密码,验证码即可,就象在使用一个没有界面的浏览器,当然更重要的是htmlunit对js的支持设置极其简单
1.添加maven的htmlunit(标红)依赖
1 <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
19 <groupId>net.sourceforge.htmlunit</groupId>
20 <artifactId>htmlunit</artifactId>
21 <version>2.18</version>
22 </dependency> </dependencies>
2.思路
定位用户名,密码,验证码框等元素,填写即可,验证码可以先把图片下载下来然后手动输入,也可以使用tess4j进行图片识别,这里是手动输入测试的网站,是一个伪ajaxsubmit,测试多次发现需要二次输入验证码才能正确登录,但令人疑惑的是两次生成的验证码一样(如果不一样说明你第一次输入错误)

public static void main(String[] args) throws Exception {
WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getOptions().setCssEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
// webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);
webClient.getOptions().setActiveXNative(false);
//ajax
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.getOptions().setUseInsecureSSL(false);
//允许重定向
webClient.getOptions().setRedirectEnabled(true);
//连接超时
webClient.getOptions().setTimeout(5000);
//js执行超时
webClient.setJavaScriptTimeout(10000*3);
//对于此网站务必开启
webClient.getCookieManager().setCookiesEnabled(true);
String url = "https://www.zuhaowan.com/login/";
HtmlPage page = webClient.getPage(url);
webClient.waitForBackgroundJavaScript(5000);
HtmlPage newPage = readyPage(page, webClient);
// String content1 = newPage.asXml();
// IOUtils.write(content1.getBytes(),new FileWriter(new File("f:/content1.txt")));
//如果页面url没有变化重新进行一次登录
if(newPage.getUrl().toString().equals(url)) {
System.out.println("出现错误请重新登录-------------");
HtmlPage result = readyPage(newPage,webClient);
System.out.println("url----------------"+result.getUrl());
System.out.println("页面----" + result.asXml());
// IOUtils.write(result.asXml(),new FileWriter(new File("f:/content2.txt")));
}
webClient.close();
}
public static HtmlPage readyPage(HtmlPage page,WebClient webClient) throws Exception {
//封装页面元素
HtmlForm form = page.getHtmlElementById("form2");
HtmlTextInput loginname = form.getInputByName("loginname");
loginname.setValueAttribute("用户名");
HtmlPasswordInput loginpwd = form.getInputByName("loginpwd");
loginpwd.setValueAttribute("密码");
//验证码输入框
HtmlTextInput verify_code = form.getInputByName("verify_code");
//验证码图片
HtmlImage verify_img = (HtmlImage) page.getElementById("verify_img");
UUID randomUUID = UUID.randomUUID();
//保存
verify_img.saveAs(new File("./src/main/resources/image/verifyimg"+ randomUUID.toString() +".png"));
System.out.println("验证码图片已保存!");
System.out.println("请输入验证码");
//手动输入验证码
Scanner scanner = new Scanner(System.in);
String code = scanner.nextLine();
System.out.println("验证码-------------" + code);
verify_code.setValueAttribute(code);
//登录按钮也可以使用page.executeJavaScript("javascript:document.getElementById('loginsubmit').click()").getNewPage();
HtmlAnchor login = page.getHtmlElementById("loginsubmit");
HtmlPage newPage = login.click();
//等待js加载
webClient.waitForBackgroundJavaScript(5000);
return newPage;
}
3.控制台部分输出截图

htmlunit 模拟登录 数字验证码的更多相关文章
- htmlunit 模拟登录 无验证码
1.模拟登录csdn,最开始的时候使用的是httpclient,网上的所有模拟登录csdn的版本都是找到lt/execution/event_id.连同用户名及密码 一起发送即可,但是目前的csdn的 ...
- C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站
原文:C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站 我们经常会碰到需要程序模拟登录一个网站,那如果网站需要填写验证码的要怎样模拟登录呢?这篇文章 ...
- Java模拟登录带验证码的教务系统(原理详解)
一:原理 客户端访问服务器,服务器通过Session对象记录会话,服务器可以指定一个唯一的session ID作为cookie来代表每个客户端,用来识别这个客户端接下来的请求. 我们通过Chrome浏 ...
- php_curl模拟登录有验证码实例
<?php/** * @author 追逐__something * @version $id */define('SCRIPT_ROOT',dirname(__FILE__).'/');$ac ...
- python爬虫实战(四)--------豆瓣网的模拟登录(模拟登录和验证码的处理----scrapy)
在利用scrapy框架爬各种网站时,一定会碰到某些网站是需要登录才能获取信息. 这两天也在学习怎么去模拟登录,通过自己码的代码和借鉴别人的项目,调试成功豆瓣的模拟登录,顺便处理了怎么自动化的处理验证码 ...
- Python爬虫模拟登录带验证码网站
问题分析: 1.爬取网站时经常会遇到需要登录的问题,这是就需要用到模拟登录的相关方法.python提供了强大的url库,想做到这个并不难.这里以登录学校教务系统为例,做一个简单的例子. 2.首先得明白 ...
- (转)php_curl模拟登录有验证码实例
三年来的第一篇博客,还记得那是一个夜深人静的夜晚, 独自一人坐在不到10平米的小屋里,指头迅速的敲打着键盘,这天真TMD热.BJ生活啊. 唉! 最近一直在参加一个论坛批量发帖的项目开发. 模拟登录,模 ...
- [PHP自动化-进阶]002.CURL模拟登录带有验证码的网站
引言:继前文<模拟登录并采集数据>,大家似乎看不过瘾,这会再出一发,模拟实现带验证码网站的登录. 这篇文章主要介绍了PHP使用CURL实现对带有验证码的网站进行模拟登录的方法,可以帮助读者 ...
- php使用curl模拟登录带验证码的网站[开发篇]
需求是这样的,需要登录带验证码的网站,获取数据,但是不可能人为一直去记录数据,想通过自动采集的方式进行,如下是试验出来的结果代码!有需要的可以参考下! <?php namespace Home\ ...
随机推荐
- POJ 2376 Cleaning Shifts 区间覆盖问题
http://poj.org/problem?id=2376 题目大意: 给你一些区间的起点和终点,让你用最小的区间覆盖一个大的区间. 思路: 贪心,按区间的起点找满足条件的并且终点尽量大的. 一开始 ...
- 20160206.CCPP体系具体解释(0016天)
代码片段(01):.指针.c+02.间接赋值.c 内容概要:内存 ///01.指针 #include <stdio.h> #include <stdlib.h> //01.取地 ...
- amazeui页面分析2
amazeui页面分析2 一.总结 1.弄清结构:这些部分都是一块一块分好了的,掌握结构之后,想替换哪块就替换哪块,想不要哪块就不要哪块,非常简单的 2.一块一块:替换十分简单 3.弄清楚大块之后,然 ...
- Android java取得实时上周的时间
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class Te ...
- Java 学习(19):Java 多线程编程
Java 多线程编程 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...
- UVA Bandwidth
题目例如以下: Bandwidth Given a graph (V,E) where V is a set of nodes and E is a set of arcsin VxV, and a ...
- [Nuxt] Update Vuex State with Mutations and MapMutations in Vue.js
You commit changes to state in Vuex using defined mutations. You can easily access these state mutat ...
- [Pug] Template Engine -- Jade/ Pug
Looking at the follow code: .wrapper - const upName = name && name.toUpperCase(); h2 | Hello ...
- php课程 3-12 回调参数怎么用
php课程 3-12 回调参数怎么用 一.总结 一句话总结:有时候需要在一个函数中使用另外一个函数,使用回调的话,那么那个函数的几十行代码就不用写了,其实很基础,就是函数名的字符串的替换,超级基础的. ...
- Mongodb in Mycat指南
1 前言 Mycat目前支持JDBC连接后端数据库,理论上支持任何数据库,如ORACLE.DB2.SQL Server等,是将其模拟为MySQL,所以对其他数据库只支持标准的SQL语句,而 ...