【解決?】wikiextractorでテキストにするときに、箇条書きの部分が消えてしまう
多少の不具合はあるものの、extract.pyのcompact関数を、以下のように変更したら、箇条書きやインデント部分の欠損はなくなっていそうです。
確認済み不具合
- {{lang-en|The Apothecary Diaries}}、{{lang-zh|药屋少女的呢喃}}のような部分が消えてしまう。
- 見出し(登場人物、主人公)などが変なところに出力されたり、なくなったりする。
変更後のコード
def compact(text, mark_headers=False):
"""Deal with headers, lists, empty sections, residuals of tables.
:param text: convert to HTML
"""
page = [] # list of paragraph
headers = {} # Headers for unfilled sections
emptySection = False # empty sections are discarded
listLevel = '' # nesting of lists
for line in text.split('\n'):
if not line:
continue
# Handle section titles
m = section.match(line)
if m:
title = m.group(2)
lev = len(m.group(1))
if Extractor.HtmlFormatting:
page.append("<h%d>%s</h%d>" % (lev, title, lev))
if title and title[-1] not in '!?':
title += '.'
if mark_headers:
title = "## " + title
headers[lev] = title
# drop previous headers
headers = { k:v for k,v in headers.items() if k <= lev }
emptySection = True
continue
# Handle page title
if line.startswith('++'):
title = line[2:-2]
if title:
if title[-1] not in '!?':
title += '.'
page.append(title)
# handle indents
elif line[0] == ':':
page.append(line.lstrip(':*#;')) # 変更点:コメントアウトを解除
# handle lists
elif line[0] in '*#;:':
if Extractor.HtmlFormatting:
i = 0
for c, n in zip_longest(listLevel, line, fillvalue=''):
if not n or n not in '*#;:':
if c:
page.append(listClose[c])
listLevel = listLevel[:-1]
continue
else:
break
# n != ''
if c != n and (not c or (c not in ';:' and n not in ';:')):
if c:
# close level
page.append(listClose[c])
listLevel = listLevel[:-1]
listLevel += n
page.append(listOpen[n])
i += 1
n = line[i - 1] # last list char
line = line[i:].strip()
if line: # FIXME: n is '"'
page.append(listItem[n] % line)
else:
page.append(line.lstrip(':*#;')) # 変更点:リストの行を追加
elif len(listLevel):
for c in reversed(listLevel):
page.append(listClose[c])
listLevel = []
# Drop residuals of lists
elif line[0] in '{|' or line[-1] == '}':
continue
# Drop irrelevant lines
elif (line[0] == '(' and line[-1] == ')') or line.strip('.-') == '':
continue
elif len(headers):
if Extractor.keepSections:
items = sorted(headers.items())
for (i, v) in items:
page.append(v)
headers.clear()
page.append(line) # first line
emptySection = False
elif not emptySection:
page.append(line)
# dangerous
# # Drop preformatted
# elif line[0] == ' ':
# continue
return page
起きた問題
wikiextractorで、xmlからテキスト化するときに、箇条書きの部分が消えてしまう。
--lists
オプションを追加すると、箇条書きの部分がそのままらしい(参照:Python】Wikipedia のデータセットを取得し、文章を抽出する方法。)が、うまくいかない。
試したこと
pip install wikiextractor==3.0.4
をしたうえで、
wikiextractor --lists ファイル名
↓
usage: wikiextractor [-h] [-o OUTPUT] [-b n[KMG]] [-c] [--html] [-l] [-ns ns1,ns2] [--templates TEMPLATES] [--no-templates] [--escapedoc] [--processes PROCESSES] [-q] [--debug] [-a] [-v] input wikiextractor: error: unrecognized arguments: --lists
WikiExtractor.pyをダウンロードした上で、
python3 -m wikiextractor.WikiExtractor --lists ファイル名
↓
usage: WikiExtractor.py [-h] [-o OUTPUT] [-b n[KMG]] [-c] [--html] [-l] [-ns ns1,ns2] [--templates TEMPLATES] [--no-templates] [--escapedoc] [--processes PROCESSES] [-q] [--debug] [-a] [-v] input WikiExtractor.py: error: unrecognized arguments: --lists
python3 WikiExtractor.py ファイル名.xml
↓
Traceback (most recent call last): File "WikiExtractor.py", line 62, in <module> from .extract import Extractor, ignoreTag ImportError: attempted relative import with no known parent package
となります。
アドバイス募集
他のユーザーの投稿を許可しているので、よろしくお願いします。
環境
Python 3.10.12
WSL2
pip 22.0.2
追加で試したこと(うまくいかず)
PythonのWikiExtractorで躓いた話で、.extractを消すと良いと書いてあったので、消して、もう一度、以下を実行
python3 WikiExtractor.py --lists ファイル名.xml
Traceback (most recent call last): File "WikiExtractor.py", line 62, in <module> from extract import Extractor, ignoreTag ModuleNotFoundError: No module named 'extract'
WikiExtractor.pyがあるGitHubに、extract.pyがあるので、このファイルを、WikiExtractor.pyと同じディレクトリに置くと、エラーが消えました。
しかし、実行しても、以下になってしまいます。
usage: WikiExtractor.py [-h] [-o OUTPUT] [-b n[KMG]] [-c] [--html] [-l] [-ns ns1,ns2] [--templates TEMPLATES] [--no-templates] [--escapedoc] [--processes PROCESSES] [-q] [--debug] [-a] [-v] input WikiExtractor.py: error: unrecognized arguments: --lists
追記(うまくいかず)
v3.0のバージョンをクローンし、extract.pyとWikiExtractor.pyを同じディレクトリに配置して、以下を実行しましたが、やはり、--listsは使えませんでした。
python3 WikiExtractor.py --lists ファイル名.xml
追記メモ
バージョン3.0でも3.04でも、WikiExtractor.pyの中に、listという記述が見当たらないので、それが原因の可能性がありそうです。
parser.add_argument("input",
help="XML wiki dump file")
groupO = parser.add_argument_group('Output')
groupO.add_argument("-o", "--output", default="text",
help="directory for extracted files (or '-' for dumping to stdout)")
groupO.add_argument("-b", "--bytes", default="1M",
help="maximum bytes per output file (default %(default)s)",
metavar="n[KMG]")
groupO.add_argument("-c", "--compress", action="store_true",
help="compress output files using bzip")
groupP = parser.add_argument_group('Processing')
groupP.add_argument("--html", action="store_true",
help="produce HTML output, subsumes --links")
groupP.add_argument("-l", "--links", action="store_true",
help="preserve links")
groupP.add_argument("-ns", "--namespaces", default="", metavar="ns1,ns2",
help="accepted namespaces")
groupP.add_argument("--templates",
help="use or create file containing templates")
groupP.add_argument("--no-templates", action="store_false",
help="Do not expand templates")
groupP.add_argument("--escapedoc", action="store_true",
help="use to escape the contents of the output <doc>...</doc>")
default_process_count = cpu_count() - 1
parser.add_argument("--processes", type=int, default=default_process_count,
help="Number of processes to use (default %(default)s)")
groupS = parser.add_argument_group('Special')
groupS.add_argument("-q", "--quiet", action="store_true",
help="suppress reporting progress info")
groupS.add_argument("--debug", action="store_true",
help="print debug info")
groupS.add_argument("-a", "--article", action="store_true",
help="analyze a file containing a single article (debug option)")
groupS.add_argument("-v", "--version", action="version",
version='%(prog)s ' + version,
help="print program version")
追記メモ
extract.pyの中にある、compact関数内の記述が原因の可能性がありそうです。
Bing AIによると、
compact関数では、箇条書き(リスト)やセクションヘッダーなどの一部の情報が削除される可能性があります。具体的には、以下のような動作をします:
:や;で始まる行(インデントや定義リストを示す)はスキップされます。
==や===で始まる行(セクションヘッダーを示す)は、ヘッダーのテキストだけが抽出され、その後の.が追加されます。
らしいです。
ということは、:や;で始まる行を考慮すれば良い可能性がある…?
追記
以下の変更だけでも、リストが表示されるようになるかと思いますが、そうすると、;の行が表示されなくなったので、
elif line[0] == ':':
page.append(line.lstrip(':*#;')) # 変更点:コメントアウトを解除
以下も必要そうです。
else:
page.append(line.lstrip(':*#;')) # 変更点:リストの行を追加