使用jsoup库解析html元标记

时间:2016-06-02 12:19:01

标签: java html html-parsing jsoup

刚开始探索Jsoup库,因为我将把它用于我的一个项目。我尝试谷歌搜索,但我找不到可以帮助我的确切答案。这是我的问题,我有一个带有meta标签的html文件,如下所示

<meta content="this is the title value" name="d.title">
<meta content="this is the description value" name="d.description">
<meta content="language is french" name="d.language">

像这样的java pojo,

public class Example {
    private String title;
    private String description;
    private String language;

    public Example() {}

    // setters and getters go here
} 

现在我要解析html文件并提取d.title内容值并存储在Example.title和d.description值“content”中并存储在Example.description中,依此类推。

我通过阅读jsoup cookbook所做的事情就像是,

Document doc = Jsoup.parse("test.html");
Elements metaTags = doc.getElementsByTag("meta");

for (Element metaTag : metaTags) {
    String content = metaTag.attr("content");
    String content = metaTag.attr("name");
}

将要做的是遍历所有元标记获取其“内容”和“名称”属性的值,但我想要的是获取“内容”属性的值,其“名称”属性是“d” .title“以便我可以将它存储在Example.title

更新: @ P.J.Meisch下面的答案实际上解决了问题,但这是我喜欢的代码太多(试图避免做同样的事情)。我的意思是我认为可以做一些像

这样的事情

String title = metaTags.getContent(“d.title”)

其中d.title是“name”属性的值 这样它会减少代码行,我没有找到这样的方法,但也许这是因为我仍然是jsoup的新手,这就是为什么我问。但是如果不存在这样的方法(如果这样做会很好,那会让生活变得更轻松)我会跟P.J.Meisch说的那样。

4 个答案:

答案 0 :(得分:9)

好的,所有代码:

Document doc = Jsoup.parse("test.html");
Elements metaTags = doc.getElementsByTag("meta");

Example ex = new Example();

for (Element metaTag : metaTags) {
  String content = metaTag.attr("content");
  String name = metaTag.attr("name");

  if("d.title".equals(name)) {
    ex.setTitle(content);
  }
  if("d.description".equals(name)) {
    ex.setDescription(content);
  }
  if("d.language".equals(name)) {
    ex.setLanguage(content);
  }
}

答案 1 :(得分:0)

将两个属性的值分配给名为content的同一变量。将name属性分配给name变量,并将其与您想要的'd.title'值进行比较。

答案 2 :(得分:0)

回答你的更新问题:使用jsoup是不可能的,因为jsoup文档只反映了html文档的xml / dom结构。你必须在metas上迭代自己,但你可以这样做:

Document doc = Jsoup.parse("test.html");

Map<String, String> metas = new HashMap<>();
Elements metaTags = doc.getElementsByTag("meta");

for (Element metaTag : metaTags) {
  String content = metaTag.attr("content");
  String name = metaTag.attr("name");
  metas.put(name, content);
}

Example ex = new Example();
ex.setTitle(metas.get("d.title"));
ex.setDescription(metas.get("d.description"));
ex.setLanguage(metas.get("d.language"));

答案 3 :(得分:0)

使用正确的特定库可简化一切

检出我的库以解析元标记内容

poshjosh/bcmetaselector

package com.bc.meta.selector;

import com.bc.meta.selector.htmlparser.AttributeContextHtmlparser;
import com.bc.meta.selector.util.SampleConfigPaths;
import com.bc.meta.ArticleMetaNames;
import com.bc.meta.impl.ArticleMetaNameIsMultiValue;
import java.util.Map;
import java.util.Iterator;
import java.util.function.BiFunction;
import org.json.simple.JSONValue;
import org.htmlparser.Parser;
import org.htmlparser.Node;
import org.htmlparser.Tag;

public class ReadMe {

    public static void main(String... args) throws Exception {

        final BiFunction<String, Node, String> nodeContentExtractor =
                (prop, node) -> node instanceof Tag ? ((Tag)node).getAttributeValue("content") : null;

        final SelectorBuilder<Node, String, Object> builder = Selector.builder();

        final Selector<Node> selector = builder.filter()
                .attributeContext(new AttributeContextHtmlparser(false))
                .configFilePaths(SampleConfigPaths.APP_ARTICLE_LIST)
                .jsonParser((reader) -> (Map)JSONValue.parse(reader))
                .propertyNames(ArticleMetaNames.values())
                .back()
                .multipleValueTest(new ArticleMetaNameIsMultiValue())
                .nodeConverter(nodeContentExtractor)
                .build();

        final Parser parser = new Parser();

        final String url = "https://edition.cnn.com/2018/06/21/africa/noura-hussein-asequals-intl/index.html";

        parser.setURL(url);

        Iterator<Node> nodes = parser.elements().iterator();

        final Map map = selector.selectAsMap(nodes, ArticleMetaNames.values());

        System.out.println("Printing meta tags data for: " + url + "\n" + map);
    }
}