首页 > 解决方案 > 维基百科中的opensearch结果为java中的jsonobject

问题描述

我想在 wikipedia 中使用 opensearch(因为结果是我要查找的)并使用 java 解析此查询的结果:

https://fr.wikipedia.org/w/api.php?action=opensearch&search=soleil&format=json

但结果看起来不像 json 格式:

    [
  "soleil",
  [
    "Soleil",
    "Soleil vert",
    "Soleilhas",
    "Soleil Royal (1749)",
    "Soleil Moon Frye",
    "Soleil levant (film)",
    "Soleil Royal (1669)",
    "Soleil trompeur",
    "Soleil Productions",
    "Soleils (association)"
  ],
  [
    "Le Soleil est l’étoile du Système solaire. Dans la classification astronomique, c’est une étoile de type naine jaune d'une masse d'environ 1,9891 ×\u202f1030 kg, composée d’hydrogène (75 % de la masse ou 92 % du volume) et d’hélium (25 % de la masse ou 8 % du volume).",
    "Soleil vert (Soylent Green) est un film américain d'anticipation réalisé par Richard Fleischer, sorti en 1973 et inspiré du roman Make room!",
    "Soleilhas est une commune française, située dans le département des Alpes-de-Haute-Provence en région Provence-Alpes-Côte d'Azur.",
    "Le Soleil-Royal est un navire de guerre français en service de 1750 à 1759. C'est un vaisseau de ligne de deuxième rang à deux ponts portant 80 canons, le troisième du nom dans la marine française.",
    "Soleil Moon Frye est une actrice américaine, née le 6 août 1976, à Glendora, Californie.",
    "Soleil levant (Rising Sun) est un thriller américain réalisé par Philip Kaufman, sorti en 1993. Le film met en vedette Sean Connery (également producteur délégué du film), Wesley Snipes, Harvey Keitel et Cary-Hiroyuki Tagawa.",
    "Le Soleil-Royal est un navire de guerre français, en service de 1669 à 1692. C'est un vaisseau de ligne de premier rang, portant 98 puis 104 canons sur trois ponts.",
    "Soleil trompeur (en russe : Утомлённые солнцем, Outomlionnyïé solntsem) est un film du réalisateur et acteur russe Nikita Mikhalkov, sorti en salles en 1994. Ce film a été récompensé par l'Oscar du meilleur film en langue étrangère et par le Grand Prix du jury au festival de Cannes.",
    "Soleil Productions est un éditeur français de bande dessinée localisé à Toulon.",
    "Soleils est une association à but humanitaire implantée sur le campus rennais de Supélec (École Supérieure d'Electricité)."
  ],
  [
    "https://fr.wikipedia.org/wiki/Soleil",
    "https://fr.wikipedia.org/wiki/Soleil_vert",
    "https://fr.wikipedia.org/wiki/Soleilhas",
    "https://fr.wikipedia.org/wiki/Soleil_Royal_(1749)",
    "https://fr.wikipedia.org/wiki/Soleil_Moon_Frye",
    "https://fr.wikipedia.org/wiki/Soleil_levant_(film)",
    "https://fr.wikipedia.org/wiki/Soleil_Royal_(1669)",
    "https://fr.wikipedia.org/wiki/Soleil_trompeur",
    "https://fr.wikipedia.org/wiki/Soleil_Productions",
    "https://fr.wikipedia.org/wiki/Soleils_(association)"
  ]
]

而且我不知道如何在我的java代码中使用它作为一个列表(使用commons-io-2.6.jar和java-json.jar):

字符串 url = " https://fr.wikipedia.org/w/api.php?action=opensearch&search=soleil&format=json ";

    String jsonText = IOUtils.toString(new URL(url), Charset.forName("UTF-8"));

    JSONObject json = new JSONObject(jsonText);

    json.getJSONArray(key); // no key in the json

标签: javajsonwikipedia-api

解决方案


维基百科的响应肯定是一个有效的 JSON,尽管结构有点不幸。他们这样做是为了节省传输(因为他们不必在响应 JSON 中包含密钥)。

现在回到那个数组结构:

  • 第一个元素是查询字符串。
  • 第二个元素是一个包含找到页面标题的数组。
  • 第三个元素是一个包含找到页面描述的数组。
  • 第四个元素是一个包含找到页面的 URL 的数组。

读取此响应的示例代码(使用 Jackson,行业标准 JSON 库):

public void printWikipediaResults() throws IOException {
    JsonNode tree = new ObjectMapper().readTree("<Wikipedia JSON>");

    // get number of results ( length of titles array )
    int totalResults = tree.get(1).size();
    // initialize a new ArrayList to store the WikiArticles into
    List<WikiArticle> results = new ArrayList<>(totalResults);
    // for each article, create a new object from the data contained in the arrays
    for (int i = 0; i < totalResults; i++) {
        results.add(new WikiArticle(
                tree.get(1).get(i).asText(),
                tree.get(2).get(i).asText(),
                tree.get(3).get(i).asText()
        ));
    }

    System.out.println("Showing results for: " + tree.get(0).asText());
    for (WikiArticle article : results) {
        System.out.println(article.title + ": " + article.url);
    }
}

public static class WikiArticle {
    public String title;
    public String desc;
    public String url;

    public WikiArticle(String title, String desc, String url) {
        this.title = title;
        this.desc = desc;
        this.url = url;
    }
}

结果:

Showing results for: soleil
Soleil: https://fr.wikipedia.org/wiki/Soleil
Soleil vert: https://fr.wikipedia.org/wiki/Soleil_vert
Soleilhas: https://fr.wikipedia.org/wiki/Soleilhas
Soleil Royal (1749): https://fr.wikipedia.org/wiki/Soleil_Royal_(1749)
Soleil Moon Frye: https://fr.wikipedia.org/wiki/Soleil_Moon_Frye
Soleil levant (film): https://fr.wikipedia.org/wiki/Soleil_levant_(film)
Soleil Royal (1669): https://fr.wikipedia.org/wiki/Soleil_Royal_(1669)
Soleil trompeur: https://fr.wikipedia.org/wiki/Soleil_trompeur
Soleil Productions: https://fr.wikipedia.org/wiki/Soleil_Productions
Soleils (association): https://fr.wikipedia.org/wiki/Soleils_(association)

推荐阅读