L’utilitaire WikiDump permet de récupérer le contenu de Wikipedia à partir d’une liste d’identifiant d’articles. L’outil se connecte sur le site fr.wikipedia.org afin de récupérer des données à jour et correctement formattées.
Pour plus de détail concernant la récupération des données de Wikipedia rendez vous sur cet article.
Pour la curiosité ou bien pour modifier son comportement voici le code source:
package com.devbypractice;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
* Classe contenant un main permettant de faire un dump
* de wikipédia.
*
*/
public class WikiDump
{
/**
* Récupère le contenu xhtml d'une url source Wikipédia en String
*
* @param sUrlSource Url Source
* @param sEncoding Encodage
* @return Le contenu du html
* @throws Exception
*/
public static String dumpWikiXhtmlToString(String sUrlSource, String sEncoding) throws Exception {
String inputLine;
URL url;
url = new URL(sUrlSource);
URLConnection urlConn = url.openConnection();
// TimeOut de 30sec
//
urlConn.setConnectTimeout(30000);
BufferedReader in = new BufferedReader(
new InputStreamReader(
urlConn.getInputStream(), sEncoding));
StringBuilder sb = new StringBuilder();
// En tête XML
//
sb.append("<?xml version=\"1.0\"?>");
sb.append("<WikiContent>");
// Copie du contenu html vers le buffer
//
while ((inputLine = in.readLine()) != null){
sb.append(inputLine);
sb.append("\n");
}
in.close();
// Fin XML
//
sb.append("</WikiContent>");
return sb.toString();
}
/**
* Charge la liste des identifiants des articles d'un fichier
* vers un liste d'entiers.
* Le fichier doit contenir un id sur chaque ligne.
*
* @param sFileName
* @return Liste des identifiants des articles
* @throws Exception
*/
public static List<Integer> loadArticleIdsFromFile(String sFileName) throws Exception
{
List<Integer> articleIds = new ArrayList<Integer>();
FileReader reader = new FileReader(sFileName);
BufferedReader buffReader = new BufferedReader(reader);
String sLine ="";
while ((sLine = buffReader.readLine())!=null) {
Integer id = Integer.parseInt(sLine);
articleIds.add(id);
}
buffReader.close();
return articleIds;
}
/**
* Affiche le mode d'emploi de la ligne de commande
*/
public static void displayUsage() {
System.out.println("Arguments:");
System.out.println("<Chemin fichier source id articles> <Chemin de destination>");
System.out.println("");
System.out.println("Notes:");
System.out.println("Le fichier source des id articles doit être un fichier " +
"comportant la liste des identifiants articles Wikipédia à récupérer, " +
"ces identifiants doivent être séparés par une fin de ligne");
System.out.println("Le chemin de destination doit exister.");
}
/**
* Nettoyage du texte.
* Les références du type [12], [3] etc... sont supprimées.
*
* @param text Texte à nettoyer
* @return Texte nettoyé
*/
public static String cleanup(String text) {
return text.replaceAll("\\[[0-9]+\\]", "");
}
/**
* Entrée principale
*
* @param args Arguments
*/
public static void main(String[] args) {
try {
// Taille en caractères UTF-16 des fichiers de sortie
// 1 Millions ~= 2 Mo
//
final int fileSizeLimit = 1000000;
// Taille courante du fichier de sortie
// mise à MAX + 1 afin qu'il soit créé lors du premier passage
//
int currentFileSize = fileSizeLimit + 1;
// Url de récupération des articles Wikipédia par leur identifant article
//
String sWikiUrlFormat = "http://fr.wikipedia.org/w/index.php?action=render&curid=%d";
FileOutputStream outStream = null;
OutputStreamWriter writer = null;
if (args.length != 2) {
displayUsage();
}
else {
// Récupération de la liste des identifiants articles à partir du fichier
//
List<Integer> articleIds = loadArticleIdsFromFile(args[0]);
// Format de destination des fichiers du contenu de wikipédia
//
String sDestinationDir = args[1];
// Pour chaque identifiant d'article
//
for (Integer articleId : articleIds) {
try {
// Si la taille courant du fichier de sortie est supérieure
// à la taille max on en crée un nouveau
//
if (currentFileSize > fileSizeLimit) {
if (writer != null) {
writer.close();
}
outStream = new FileOutputStream(sDestinationDir + "\\" + articleId + ".txt");
writer = new OutputStreamWriter(outStream, "UTF-16");
currentFileSize = 0;
}
// Construction de l'url de l'article
//
String sWikiUrl = String.format(sWikiUrlFormat, articleId);
// Récupération du contenu de l'article
//
String sWiki = dumpWikiXhtmlToString(sWikiUrl, "UTF-8");
// Chargement XML du contenu
//
InputSource is = new InputSource(new StringReader(sWiki));
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(is);
//writer.write("========= " + articleId + " ==========\n");
// Ciblage du contenu à récupérer via XPath
//
NodeList nl = XPathProcessor.getInstance().EvaluateMutli(
"/WikiContent/p", doc);
// Pour chaque noeud
//
for (int i = 0; i < nl.getLength(); i++) {
String sContent = "";
try {
Node node = nl.item(i);
// Récupération du texte
//
sContent = node.getTextContent();
// Nettoyage
//
sContent = cleanup(sContent);
// Ecriture dans le fichier
//
writer.write(sContent);
writer.write("\n\n");
writer.flush();
// Augmentation de la taille du fichier courant
//
currentFileSize += sContent.length() + 2;
}
catch (Exception e2) {
String sLog = "Impossible de récupérer le paragraphe " + i + " pour id=" + articleId;
System.out.println(sLog);
}
}
}
catch (Exception e3) {
String sLog = "Impossible de récupérer l'article id=" + articleId + "\n";
System.out.println(sLog);
e3.printStackTrace();
}
}
writer.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Cet utilitaire nécessite une classe de gestion des requêtes XPath, dont le code est à cette adresse.
Une version déjà compilée de WikiDump est disponible à cette adresse.