💧

pdfから英語テキストを抽出し、無料で日本語に変換するプログラム

3 min read

初めに

今回、arxivのpdfから英語のテキスト抽出を行い、googletransを使って日本語に変換します。

※googletransには文字数制限があります。
※googletransはGoogle翻訳の制限に依存していていつまでもライブラリが利用可能とは限らない(2021/01/01現在使えなくなってるみたいです)

モジュール

import os
import re
import tqdm
import argparse
import time
from io import StringIO
from glob import glob
import pandas as pd

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter, PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBoxHorizontal
from pdfminer.pdfpage import PDFPage

from googletrans import Translator
translator = Translator()

ディレクトリの指定

pdf_dir = ""
path = os.path.join(pdf_dir, '*.pdf')
files = glob(path)
print(files,len(files))


上記のpdfを読み込むと以下のように出力されます。

['arxiv.pdf', 'arxiv2.pdf'] 2

PDFからテキスト抽出・日本語変換


#  文字数を区切ってリストに保存
def split_en_txt(str, num):
    list_en_txt = []
    for i in range(num):
        list_en_txt.append(str[i::num])
    list_en_txt = ["".join(i) for i in zip(*list_en_txt)]
    rem = len(str) % num
    if rem:
        list_en_txt.append(str[-rem:])
    return list_en_txt

#  英語から日本語に変換
def en_convert_to_ja(txt):
    ja_txt = []
    for en_txt in txt:
        trans_de_ja = translator.translate(en_txt, src='en', dest='ja')
        ja_txt.append(trans_de_ja.text)
    return ja_txt

#  分割した日本語のリストを結合
def map_list(list_txt):
    map_list = []
    ja_txt = ''
    map_list = map(str, list_txt)
    ja_txt = ''.join(map_list)
    return ja_txt

# あらかじめpandasでデータフレームを作成し、その中にテキストを入れていきます。
df = pd.DataFrame({'file_id': ['A1'],
                   'en_txt': ['B1'],
                   'ja_txt': ['C1']})
for i,path_pdf in enumerate(tqdm.tqdm(files)):
    file_id_with_version = os.path.splitext(os.path.basename(path_pdf))[0]
    
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    laparams.detect_vertical = True
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = open(path_pdf, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    maxpages = 0
    caching = True
    pagenos=set()
    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages,caching=caching, check_extractable=True):
        interpreter.process_page(page)
    en_txt = retstr.getvalue()
    list_split_en_txt = split_en_txt(en_txt,1000)
    #  一気に日本語変換するとエラーがよくでるので60秒ほど間をおきます
    time.sleep(60)
    list_ja = en_convert_to_ja(list_split_en_txt)
    ja_txt = map_list(list_ja)
    df.loc[i,'file_id'] = file_id_with_version
    df.loc[i,'en_txt'] = en_txt
    df.loc[i,'ja_txt'] = ja_txt
    fp.close()
    device.close()
    retstr.close()  

出力

csvファイルとtsvファイルで出力します

df.to_csv("test.csv",index=False,encoding='utf-8')
df.to_csv("test.tsv",sep='\t',index=False,encoding='utf-8')
gf = pd.read_csv("test.csv",encoding='utf-8')
gf

出力し、再度読むこむと以下のような感じになります。

Discussion

ログインするとコメントできます