如果您访问 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
似乎发生了以下任一情况:
如果是后者,请告诉我如何更改我的代码以使其与 HtmlUnit 3.10.0 一起使用。
如果是前者,请告诉我,以便我将其报告给 HtmlUnit 开发人员:https://htmlunit.sourceforge.io/submittingBugs.html
现在,我能想到的最好的解决方法是找出上述代码适用的最新版本的 HtmlUnit,然后恢复使用该版本。如果您能想到一种解决方法,可以让我继续使用最新版本的 HtmlUnit,同时仍然进入上述第二个网页的地址块,请告诉我。
提前谢谢您,
GodsGiftToJava
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("-------------------------------------------------------------------------------");
}
希望它也适合您...