0

我想动态调用 jsoup 中的方法。这是我的用例,我实际上是在 jsoup 中调用多个 select dom 方法来遍历内部,例如,

Document doc = Jsoup.connect("http://test.com").get();
String companyName = doc.select("div[class=\"_name\"]").select("span[class="\_name\"]").text();

我可以动态实现相同的效果吗?

Document doc = Jsoup.connect("http://test.com").get();
String pattern = "select("div[class=\"_name\"]").select("span[class="\_name\"]").text()";
String companyName = doc.pattern;

我知道我们可以使用反射来实现,但不确定如何实现这种行为,因为模式字符串将是动态的并且可能有 n 个 dom 选择器。

让我知道上述动力是否可能。

4

2 回答 2

1

是的,这是可能的,您所要做的就是重复调用select()Document 对象上的方法,直到您枚举了所有选择器,然后调用该text()方法。

您甚至可以将所有选择器合二为一,因为select(div[class=foo]).select(span[class=bar]).text()相当于select(div[class=foo] span[class=bar]).text()可以简化为select(div.foo span.bar).text()

因此,也许您甚至可以丢弃整个反射事物并动态创建正确且直接的选择器来满足您的需求。

  Document doc = Jsoup.connect("http://test.com").get();
  String companyName = doc.select("div.foo span.bar").text();

这是使用链接:

Document doc = Jsoup.connect("http://test.com").get();
List<String> criterias = Arrays.asList("div.foo", "span.bar");
Document tmpDoc = doc;
for (String criteria: criterias) {
    if (tmpDoc != null)
        tmpDoc = tmpDoc.select(criteria);
}
// now you have traversed the whole criterias just get the text
String companyName = tmpDoc.text();

否则,这与使用反射相同:

Document doc = Jsoup.connect("http://test.com").get();
List<String> criterias = Arrays.asList("div.foo", "span.bar");
Method select = doc.getClass().getMethod("select", String.class);
Document tmpDoc = doc;
for (String criteria: criterias) {
    if (tmpDoc != null)
        tmpDoc = (Document)select.invoke(tmpDoc, new Object[] {criteria});
}
// now you have traversed the whole criterias just get the text
String companyName = tmpDoc.text();
于 2012-08-31T15:23:03.673 回答
0

如果您只想支持n 个 dom 选择器,那么您实际上不需要反射,因为您可以将它们组合在一个选择器字符串中:

Document doc = Jsoup.connect("http://test.com").get();
String pattern = "div[class=\"_name\"] span[class=\"_name\"]"; // Just separate with spaces
String companyName = doc.select(pattern).text();
于 2012-08-31T15:22:51.900 回答