Java HtmlUnit 不再能够查找列表<HtmlFieldSet> 使用 getByXPath(@class=)

问题描述 投票:0回答:1

如果您访问 https://parcelinquirytreasurer.cochise.az.gov/,在文本字段中输入 1010501508 并单击“提交”,您将看到一个新网页(第 2 页)。第 2 页上有一个邮寄地址。如果您检查它,您会看到它以 fieldset class="addressblock" 开头。无论您是在 Windows 11 上使用 Chrome 还是在 Ubuntu 24.04 Daily Build 上使用 Firefox,您都会得到这一点。

我能够使用 Java (Oracle JDK 21.0.2) 和从 jar-download.com 下载的两个一年前版本的 HtmlUnit(版本 02.69.00 和 02.70.00)在 Ubuntu 24.04 Daily Build 上重现这一点。

我使用了以下代码:

import java.util.*;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftwaer.htmlunit.html.*;
import com.gargoylesoftware.htmlunit.javascript.*;

class HtmlFieldSetClass {
    public static void main(String[] args) {
        try {
            System.getProperties().put("org.apache.commons.logging.simplelog.defaultlog", "fatal");
            java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(java.util.logging.Level.OFF);
            final WebClient webClient = new WebClient(BrowserVersion.BEST_SUPPORTED);
            webClient.getOptions().setCssEnabled(false);
            webClient.getOptions().setThrowExceptionOnScriptError(false); 
            webClient.setJavaScriptErrorListener(new SilentJavaScriptErrorListener()); 
            webClient.setCssErrorHandler(new SilentCssErrorHandler());  
            HtmlPage page = webClient.getPage("https://parcelinquirytreasurer.cochise.az.gov/");
            webClient.waitForBackgroundJavaScriptStartingBefore(1000000000);    
            page = (HtmlPage) page.getEnclosingWindow().getEnclosedPage(); 
            List<HtmlForm> forms = page.getByXPath("//form[@method='post']");
            Iterator formsIterator = forms.iterator();
            HtmlForm form = (HtmlForm) formsIterator.next();
            List<HtmlInput> his = form.getByXPath("//input[@value='Submit']");
            Iterator hisIterator = his.iterator();
            HtmlInput hi = (HtmlInput) hisIterator.next();
            HtmlTextInput textField = form.getInputByName("parcelNumber_input");  
            textField.click();
            textField.setValueAttribute("1010501508");  
            webClient.waitForBackgroundJavaScript(10000000);
            webClient.waitForBackgroundJavaScriptStartingBefore(1000000);
            webClient.getOptions().setJavaScriptEnabled(true);
            HtmlPage page2 = hi.click();
            page2.getEnclosingWindow().getJobManager().waitForJobs(10000000);
            webClient.waitForBackgroundJavaScriptStartingBefore(1000000000);
            List<HtmlFieldSet> addressblocks = page2.getByXPath("//fieldset[@class='addressblock']");
            System.out.println("addressblocks.size() = " + addressblocks.size());
        }
        catch (Exception e) {
            System.out.println("Exception:  " + e.toString());
        }
    }
}

我得到的输出为:addressblocks.size() = 1

我尝试使用最新版本的 HtmlUnit 和之前的版本(版本 03.09.0 和 03.10.0)重现同样的事情,两者都是从 htmlunit.sourceforge.io 下载的。我在代码中唯一更改的内容如下:我替换了所有 com.gargoylesoftware。与组织。

我期望看到相同的输出:addressblocks.size() = 1

相反,我得到以下输出:addressblocks.size() = 0

似乎发生了以下任一情况:

  1. HtmlUnit 在 2.70.0 和 3.09.0 版本之间引入了一个错误。
  2. 使用 HtmlUnit 获取 fieldset class="something" 的协议已从版本 2.70.0 更改为版本 3.10.0

如果是后者,请告诉我如何更改我的代码以使其与 HtmlUnit 3.10.0 一起使用。

如果是前者,请告诉我,以便我将其报告给 HtmlUnit 开发人员:https://htmlunit.sourceforge.io/submittingBugs.html

现在,我能想到的最好的解决方法是找出上述代码适用的最新版本的 HtmlUnit,然后恢复使用该版本。如果您能想到一种解决方法,可以让我继续使用最新版本的 HtmlUnit,同时仍然进入上述第二个网页的地址块,请告诉我。

提前谢谢您,

GodsGiftToJava

java htmlunit
1个回答
0
投票

HtmlUnit 3.0 是一个主要版本 - 有些东西不兼容。

变更报告 (https://www.htmlunit.org/changes-report.html#a3.0.0) 提到了所有内容。

您必须调整有关为搜索字段提供值的代码 - 将 setValueAttribute 替换为 type。因此,您没有到达预期的页面,因此 xpath 找不到您的元素。

这个稍微简化的代码在这里工作

final String url = "https://parcelinquirytreasurer.cochise.az.gov/";

try (final WebClient webClient = new WebClient(BrowserVersion.FIREFOX)) {
    webClient.getOptions().setCssEnabled(false);
    webClient.getOptions().setThrowExceptionOnScriptError(false);

    HtmlPage page = webClient.getPage("https://parcelinquirytreasurer.cochise.az.gov/");
    webClient.waitForBackgroundJavaScriptStartingBefore(10_000);
    page = (HtmlPage) page.getEnclosingWindow().getEnclosedPage();

    List<HtmlForm> forms = page.getByXPath("//form[@method='post']");
    Iterator<HtmlForm> formsIterator = forms.iterator();
    HtmlForm form = formsIterator.next();

    List<HtmlInput> his = form.getByXPath("//input[@value='Submit']");
    Iterator<HtmlInput> hisIterator = his.iterator();
    HtmlInput hi = hisIterator.next();

    HtmlTextInput textField = form.getInputByName("parcelNumber_input");
    textField.type("1010501508");

    textField.click();
    textField.setValueAttribute("1010501508");

    HtmlPage page2 = hi.click();
    webClient.waitForBackgroundJavaScriptStartingBefore(10_000);

    List<HtmlFieldSet> addressblocks = page2.getByXPath("//fieldset[@class='addressblock']");
    System.out.println("-------------------------------------------------------------------------------");
    System.out.println(addressblocks.iterator().next().asNormalizedText());
    System.out.println("-------------------------------------------------------------------------------");
}

希望它也适合您...

© www.soinside.com 2019 - 2024. All rights reserved.