Wikipedia bietet einen Speicherauszug aller Seiten. Obwohl es sich um eine große Datenmenge handelt, wird ein Index so vorbereitet, dass er beim Komprimieren verarbeitet werden kann. Lassen Sie uns die Daten tatsächlich abrufen.
Eine Beschreibung der Dump-Daten finden Sie unten.
Achten Sie darauf, das entpackte XML aufgrund der großen Dateigröße nicht in einem normalen Editor oder Browser zu öffnen.
Die Daten für die japanische Version von Wikipedia sind unten.
Ab der Ausgabe zum 1. Mai 2020, die zum Zeitpunkt des Schreibens verfügbar war, werden wir die folgenden zwei Dateien verwenden.
Das erste XML sind die Körperdaten. Da es bereits komprimiert ist und diese Größe hat, wird es beim Erweitern eine lächerliche Größe sein, aber diesmal wird es nicht erweitert, da es so betrachtet wird, dass es beim Komprimieren behandelt werden kann.
Der zweite Index wird erweitert. Es wird ungefähr 107 MB sein.
Der folgende Artikel untersucht die Struktur von gedumpten XML-Tags.
Die Struktur des Hauptteils ist wie folgt. Ein Element wird in einem Seiten-Tag gespeichert.
<mediawiki>
<siteinfo> ⋯ </siteinfo>
<page> ⋯ </page>
<page> ⋯ </page>
⋮
<page> ⋯ </page>
</mediawiki>
Die bz2-Datei komprimiert nicht einfach die gesamte XML-Datei, sondern besteht aus Blöcken mit 100 Elementen. Sie können den Block herausnehmen und punktgenau bereitstellen. Diese Struktur heißt ** Multistream **.
siteinfo | page × 100 | page × 100 | ⋯ |
Der Index hat für jede Zeile die folgende Struktur.
bz2 Offset:id:title
Überprüfen Sie die tatsächlichen Daten.
$ head -n 5 jawiki-20200501-pages-articles-multistream-index.txt
690:1:Wikipedia:Protokoll hochladen April 2004
690:2:Wikipedia:Aufzeichnung löschen/Vergangenes Protokoll Dezember 2002
690:5:Ampasand
690:6:Wikipedia:Sandbox
690:10:Sprache
Um die Länge eines Blocks ab 690 zu ermitteln, müssen Sie wissen, wo der nächste Block beginnt.
$ head -n 101 jawiki-20200501-pages-articles-multistream-index.txt | tail -n 2
690:217:Liste der Musiker(Gruppe)
814164:219:Liste der Songtitel
Da es sich bei jedem Artikel um einen Artikel handelt, können Sie die Gesamtzahl der Artikel ermitteln, indem Sie die Anzahl der Zeilen zählen. Es gibt ungefähr 2,5 Millionen Artikel.
$ wc -l jawiki-20200501-pages-articles-multistream-index.txt
2495246 jawiki-20200501-pages-articles-multistream-index.txt
Lassen Sie uns tatsächlich einen bestimmten Gegenstand herausnehmen. Das Ziel ist "Qiita".
Suche nach "Qiita".
$ grep Qiita jawiki-20200501-pages-articles-multistream-index.txt
2919984762:3691277:Qiita
3081398799:3921935:Template:Qiita tag
3081398799:3921945:Template:Qiita tag/doc
Ignorieren Sie die Vorlage und zielen Sie auf die erste ID = 3691277.
Grundsätzlich gibt es 100 Elemente pro Block, aber es gibt Ausnahmen und sie scheinen nicht ausgerichtet zu sein. Überprüfen Sie daher manuell die Startposition des nächsten Blocks.
2919984762:3691305:Category:Gabuns bilaterale Beziehungen
2920110520:3691306:Category:Japan-Cameloon-Beziehungen
Sie haben alle Informationen, die Sie benötigen.
id | Block | 次のBlock |
---|---|---|
3691277 | 2919984762 | 2920110520 |
Python
Starten Sie Python.
$ python
Python 3.8.2 (default, Apr 8 2020, 14:31:25)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
Öffnen Sie die komprimierte Datei.
>>> f = open("jawiki-20200501-pages-articles-multistream.xml.bz2", "rb")
Geben Sie den Versatz an, um den Block mit dem Qiita-Element abzurufen.
>>> f.seek(2919984762)
2919984762
>>> block = f.read(2920110520 - 2919984762)
Erweitern Sie den Block, um die Zeichenfolge abzurufen.
>>> import bz2
>>> data = bz2.decompress(block)
>>> xml = data.decode(encoding="utf-8")
Und überprüfen Sie den Inhalt. Enthält 100 Seiten-Tags.
>>> print(xml)
<page>
<title>Category:Bürgermeister Eba</title>
<ns>14</ns>
<id>3691165</id>
(Weggelassen)
Es ist umständlich, also analysieren Sie es als XML. Das Root-Element wird zum Parsen benötigt. Fügen Sie es daher entsprechend hinzu.
>>> import xml.etree.ElementTree as ET
>>> root = ET.fromstring("<root>" + xml + "</root>")
Überprüfen Sie den Inhalt. Unter dem Stamm befinden sich 100 Seiten-Tags.
>>> len(root)
100
>>> [child.tag for child in root]
['page', 'page',(Weggelassen), 'page']
Rufen Sie die Seite ab, indem Sie die ID angeben. Das Argument von "find" ist eine Notation namens XPath.
>>> page = root.find("page/[id='3691277']")
Und überprüfen Sie den Inhalt.
>>> page.find("title").text
'Qiita'
>>> page.find("revision/text").text[:50]
'{{Infobox Website\n|Site-Name=Qiita\n|Logo=\n|Bildschirmfoto=\n|Schädel'
Als Datei speichern.
>>> tree = ET.ElementTree(page)
>>> tree.write("Qiita.xml", encoding="utf-8")
Sie erhalten eine Datei, die folgendermaßen aussieht:
Qiita.xml
<page>
<title>Qiita</title>
<ns>0</ns>
<id>3691277</id>
<revision>
<id>77245770</id>
<parentid>75514051</parentid>
<timestamp>2020-04-26T12:21:10Z</timestamp>
<contributor>
<username>Linuxmetel</username>
<id>1613984</id>
</contributor>
<comment>Erklärung zu Qiitas Kontroverse und LGTM-Aktie hinzugefügt</comment>
<model>wikitext</model>
<format>text/x-wiki</format>
<text bytes="4507" xml:space="preserve">{{Infobox Website
|Site-Name=Qiita
(Weggelassen)
[[Category:Japanische Website]]</text>
<sha1>mtwuh9z42c7j6ku1irgizeww271k4dc</sha1>
</revision>
</page>
Eine Reihe von Abläufen wird in einem Skript zusammengefasst.
Speichern und verwenden Sie den Index in SQLite.
SQLite
Das Skript konvertiert den Index in TSV und generiert SQL zur Aufnahme.
python conv_index.py jawiki-20200501-pages-articles-multistream-index.txt
Es werden drei Dateien generiert.
In SQLite importieren.
sqlite3 jawiki.db ".read jawiki-20200501-pages-articles-multistream-index.sql"
Sie sind jetzt bereit.
Die Datenbank enthält nur den Index, daher benötigen Sie die Datei xml.bz2 im selben Verzeichnis. Benennen Sie es nicht um, da die Datenbank den Dateinamen xml.bz2 enthält.
Wenn Sie die Datenbank und den Elementnamen angeben, wird das Ergebnis angezeigt. Standardmäßig wird nur der Inhalt des Text-Tags angegeben. Wenn Sie jedoch "-x" angeben, werden alle Tags im Seiten-Tag ausgegeben.
python mediawiki.py jawiki.db Qiita
python mediawiki.py -x jawiki.db Qiita
Sie können in eine Datei ausgeben.
python mediawiki.py -o Qiita.txt jawiki.db Qiita
python mediawiki.py -o Qiita.xml -x jawiki.db Qiita
mediawiki.py kann als Bibliothek verwendet werden.
import mediawiki
db = mediawiki.DB("jawiki.db")
print(db["Qiita"].text)
Artikel über Multistream- und bz2-Module.
Ich habe auf die Indexspezifikationen von Wikipedia verwiesen.
Die ElementTree XML-API verwies auf die Dokumentation.
Ich habe untersucht, wie SQLite bei der Verarbeitung von Beispielsatzdaten verwendet wird.
Recommended Posts