关于HtmlUnit自动化 -- 网页自动化测试

本文介绍了作者如何使用HtmlUnit库进行网页自动化测试,实现登录并修改网站元标题的功能。通过读取Excel表格数据,遍历并更新指定网页的域名后缀信息。文中还对比了HtmlUnit和Jsoup的区别,并分享了代码优化的想法。
摘要由CSDN通过智能技术生成

htmkl官网 :  https://htmlunit.sourceforge.io/     (本次用的为HtmlUnit 2.51 )

  这是小编第一次记录自己的博客,如果不对的地方请留言指正,感谢!🤞

  近期公司网站的的 meta title 需要更换了,给了一个excl,600多行,我自己懒得搞,于是就想着可以不可用网站自动化测试,让代码帮我点,于是有了这次,闲言少叙,上代码!

  • 代码主体
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.*;
import com.gargoylesoftware.htmlunit.util.Cookie;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import org.apache.commons.io.input.BufferedFileChannelInputStream;
import sun.jvm.hotspot.code.Location;

import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Httpunit自动化 {
    public static void main(String[] args) throws IOException, BiffException {

        //获取表格的所有数据
        Map<String, String> domian_list = getDomains();

        //设置网址
        String pageUrl = "这里是你需要爬取的网页";

        //创建一个webclient  
        //-- 127.0.0.1/8001/http,是以127.0.0.1的8001端口用http的方式启用本地代理
        WebClient webClient = new WebClient(BrowserVersion.CHROME,"127.0.0.1",8001,"http");

        //参数设置
        //启动JS
        webClient.getOptions().setJavaScriptEnabled(true);
        //禁用CSS,可避免自动二次请求css进行渲染
        webClient.getOptions().setCssEnabled(false);
        //启动客户端重定向
        webClient.getOptions().setRedirectEnabled(true);
        //运行错误时,是否抛出异常
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        //禁用日志打印
        Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
        //设置超时
        webClient.getOptions().setTimeout(10000);
        //忽略证书
        webClient.getOptions().setUseInsecureSSL(true);
        //设置Ajax
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        //设置cookie
        webClient.getCookieManager().setCookiesEnabled(true);

        //获取页面
        HtmlPage loginPage = webClient.getPage(pageUrl + "signin.html");
        // 根据form的名字获取页面表单,也可以通过索引来获取:loginPage.getForms().get(0)
        HtmlForm form = loginPage.getForms().get(0);
        //获取姓名输入框
        HtmlTextInput username = form.getInputByName("u");
        //获取密码输入框
        HtmlPasswordInput userPass = form.getInputByName("p");
        //获取谷歌身份码
        HtmlTextInput googleCode = form.getInputByName("g");
        //设置用户和密码
        username.setValueAttribute("用户名");
        userPass.setValueAttribute("密码");
        //等待输入谷歌验证码
        System.out.print("请输入谷歌验证码: ");
        Scanner input = new Scanner(System.in);
        String code = input.nextLine();
        input.close();
        //设置谷歌验证码
        googleCode.setValueAttribute(code);
        //获取提交按钮
        HtmlInput button = form.getInputByName("signin");
        HtmlPage indexPage = button.click();
        //等待JS驱动dom完成后获得还原后的网页
        webClient.waitForBackgroundJavaScript(10000);
        if (indexPage.getTitleText().equals("Admin/Summary") || indexPage.getTitleText().equals("Admin Settings")) {
            System.out.println("登陆成功!");
        }else{
            System.out.println(indexPage.asXml());
            //关闭webclient
            webClient.close();
            System.out.println("登陆失败,关闭程序!");
            return;
        }
        int pas = 1;
        for (String tdl : domian_list.keySet()) {
            if(pas < 9) {
                pas++;
                continue;
            }
            //登陆后直接跳转路由至 Tlds 页面
            HtmlPage TldsPage = webClient.getPage(pageUrl + "****.html");
            webClient.waitForBackgroundJavaScript(10000);
            System.out.println("开始第" + pas + "次自动操作!");
            System.out.println("进入" + TldsPage.getTitleText() + "页面!");
            //精准定位域名后缀列表
            List<HtmlAnchor> domains = TldsPage.getByXPath("//tr//td[1]//a");
            int countA = getCountForA(domains, tdl);
            if (countA != -1) {
                System.out.println("找到匹配项 :  ==>  ");
                System.out.println(domains.get(countA).getHrefAttribute());
                HtmlPage tldsinfo = domains.get(countA).click();
                webClient.waitForBackgroundJavaScript(10000);
                System.out.println("进入" + tldsinfo.getTitleText() + "页面!");
                HtmlTableCell htmlTd = (HtmlTableCell) tldsinfo.getByXPath("//form[1]//tr[1]//td[2]").get(0);
                String msg = "." + htmlTd.getTextContent().toLowerCase().trim();
                if (msg.contains(tdl)) {
                    System.out.println("匹配到了 :" + msg + "==>" + tdl);
                    HtmlForm tld_inf_form = tldsinfo.getForms().get(1);
                    HtmlTextInput title = tld_inf_form.getInputByName("title");
                    System.out.println(title.getValueAttribute() + "  ==>  " + domian_list.get(tdl));
                    title.setValueAttribute(domian_list.get(tdl));
                    HtmlInput save = tld_inf_form.getInputByValue("Save Tld Info");
                    save.click();
                    webClient.waitForBackgroundJavaScript(10000);
                    System.out.println("修改完成,返回域名列表!");
                    BufferedWriter file = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("domain_log.txt",true), "utf-8"));
                    file.write("操作次数:" + pas +"     操作域名后缀:" + tdl);
                    file.newLine();
                    file.close();
                }
                if(tdl.equals(".yachts")){
                    webClient.close();
                    System.out.println("第一阶段任务完成,关闭程序!");
                    return;
                }
            } else {
                System.out.println("未找到匹配域名:" + tdl);
                BufferedWriter file = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("log.txt",true), "utf-8"));
                file.write(tdl);
                file.newLine();
                file.close();
                System.out.println("未找到域名已经列入缺省列表中!");
                continue;
            }
            pas++;
        }
            //关闭webclient
            webClient.close();
        System.out.println("关闭程序!");
    }
  • Excel 表格读取函数。--  getDomains()
static private Map<String, String> getDomains() throws IOException, BiffException {
        File domains = new File("/Users/Shared/Hugh/work/autoWeb/src/Dynadot Meta Title Restructure List_Sept2021.xls");
        //检验文件是否存在
        if(!domains.exists()){
            System.out.println(domains.getName() + "不存在!");
            return null;
        }else {
            System.out.println("正在读取EXCL表格!");
        }
        Workbook workbook = Workbook.getWorkbook(domains);
        Sheet sheet= workbook.getSheet(0);
        Cell cell = sheet.getCell(0,0);
        Cell content ;
        System.out.println(cell);
        Map<String,String> listCell = new LinkedHashMap<>();
        for (int i = 2 ;i < 520;i++){
            cell = sheet.getCell(0,i);
            content = sheet.getCell(1,i);
            String dtl = content.getContents();
            if(dtl.indexOf("Domains") > 0){
                dtl =  dtl.substring(0,dtl.indexOf("Domains")).trim().toLowerCase();
            }else if(dtl.indexOf("Domain") > 0){
                dtl =  dtl.substring(0,dtl.indexOf("Domain")).trim().toLowerCase();
            }
            listCell.put(dtl,content.getContents());
        }
        workbook.close();
        System.out.println("表格数据读取完毕!");
        return listCell;
    }
  • 列表内容比对函数  --  getCountForA(List<HtmlAnchor> domains,String tdl) 
static private int getCountForA(List<HtmlAnchor> domains,String tdl) {
        int msg =-1;
        for (int i = 0; i < domains.size(); i++) {
            String tdls = domains.get(i).getTextContent();
            if (tdls.equals(tdl.trim())) {
                System.out.println("The domain name :" + domains.get(i).getTextContent());
                System.out.println("The tdl is :" + tdl);
                System.out.println("The result is true!");
                msg = i;
                break;
            }
        }
        return msg;
    }

因为本人比较懒,只是为了快速的将工作做完,所以这个代码还有很大的优化空间,比如:

  1. 断线重连
  2. 比如说配合Swing做成可视化的插件或者程序。
  3. 将网页内容部分变成可输入的变量等等。

说一下个人对HtmlUnit的理解吧

  • HtmlUnit和Jsoup


    Jsoup: 

     jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

    HtmlUnit:

    它可以简单的理解为是一个嵌入式没有界面的浏览器。

    HtmlUnit相对于Jsoup最大的不同之处大概就是,Jsoup一般只用于静态网站的爬取,而HtmlUnit则是被用来进行网页自动化测试的,基于这些特点,仅仅考虑静态网站的角度下,二者从运行速度上来说,Jsoup还是好点的。但是涉及到网页复杂操作就不行了。

    第一次写博客,因为本人对HtmIunit的理解仅仅体现在上述代码,就不过多的板门弄斧了,也希望以后可以给大家提供更多干货,一起加油!
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值