Parsing et utilitaires
Écrire un extracteur consiste surtout à transformer une réponse en champs de modèle. Le package utils est la boîte à outils, et deux bibliothèques font le gros du travail.
JSON : nanojson
Le parsing JSON utilise nanojson (com.grack.nanojson) : JsonObject, JsonArray, JsonParser, JsonWriter. Un parse typique :
JsonObject root = JsonParser.object().from(downloader.get(url).responseBody());
JsonArray items = root.getArray("results");
for (int i = 0; i < items.size(); i++) {
JsonObject item = items.getObject(i);
}JsonUtils ajoute un accès par chemin pointé pour éviter d'enchaîner getObject à la main, et lève une ParsingException (plutôt que de retourner null) quand un chemin est manquant :
JsonUtils.getString(root, "data.items.0.title");
JsonUtils.getArray(root, "contents.section.items");
JsonUtils.toJsonObject(responseBody); // parse et enveloppe les erreursHTML : jsoup
Le scraping HTML utilise jsoup (org.jsoup) : Jsoup.parse, Document, Element, Elements.
Document doc = Jsoup.parse(downloader.get(url).responseBody());
for (Element e : doc.getElementsByClass("writing")) {
collector.commit(new MyCommentItemExtractor(e));
}Regex : Parser
Parser enveloppe java.util.regex avec des helpers adaptés à l'extracteur, qui lèvent une Parser.RegexException (une ParsingException) en l'absence de correspondance, de sorte qu'une correspondance échouée soit une erreur d'extraction, pas un null silencieux :
Parser.matchGroup1("v=([\\w-]+)", url);
Parser.matchGroup(pattern, input, 2);
Parser.matchGroup1MultiplePatterns(patterns, input); // en essaie plusieurs, la première qui touche
Parser.isMatch(pattern, input);Helpers du quotidien : Utils
Utils est le fourre-tout vers lequel on se tourne en permanence :
Utils.isNullOrEmpty(str | collection | map);
Utils.removeNonDigitCharacters("1,234 views"); // -> "1234"
Utils.mixedNumberWordToLong("1.2M"); // compteurs suffixés -> long
Utils.getBaseUrl(url); Utils.getQueryValue(url, "v");
Utils.replaceHttpWithHttps(url); Utils.encodeUrlUtf8(s); Utils.decodeUrlUtf8(s);
Utils.EMPTY_STRING;Exécuter du JavaScript
Quand un service a besoin d'exécuter le JS du player (le cas de YouTube, voir Dans YouTube), JavaScript enveloppe Rhino :
JavaScript.compileOrThrow(fn);
JavaScript.run(fn, "functionName", args...);et le package jsextractor (Lexer, JavaScriptExtractor.matchToClosingBrace) extrait un corps de fonction équilibré depuis du code minifié. À noter que dans ce fork, le chemin de signature YouTube délègue le plus souvent à une API de décodage distante plutôt que d'exécuter ce JS localement.
Mise en cache des manifestes
ManifestCreatorCache est un petit cache borné et sérialisable que les créateurs de manifeste DASH utilisent pour qu'une requête répétée ne reconstruise pas le même manifeste à partir de zéro.
