Si vous souhaitez traduire un PDF, la fonction standard de Google Translate vient à l'esprit en premier, mais il y a une limite de taille de fichier et c'est un problème en fonction du PDF. Dans Article précédent, j'ai frappé l'API Google Translate pour traduire le texte anglais en japonais. Si le texte que vous souhaitez lire est PDF, vous pouvez utiliser Google Documents ou Adobe Acrobat pour extraire le texte, mais il y a un inconvénient que le nombre d'étapes est important. Ici aussi, il semble que Python puisse faire une série de travaux en utilisant une bibliothèque appelée PDF Miner. J'ai beaucoup évoqué les articles suivants. [PDF Miner] Extraction de texte à partir d'un PDF
Le script créé est ci-dessous. https://github.com/KanikaniYou/translate_pdf
Tous les fichiers PDF d'un certain dossier sont extraits, traduits et générés sous forme de fichiers texte.
Etant donné que même les chaînes de caractères inutiles sont prises après l'extraction avec PDFMiner (chaînes de caractères avec le même symbole que "......", etc. C'est dans la table des matières, etc.), les fichiers texte extraits sont rassemblés comme un fichier intermédiaire. J'essaie de permettre aux gens de supprimer les pièces inutiles.
Le flux global du travail de traduction 0. démarrage rapide| Google Cloud Translation API Documentation | Google Cloud PlatformObtenez l'API Google Translate en vous référant à
Ce sera. Comme mentionné ci-dessus, en regardant manuellement le fichier texte après 1., vous pouvez vérifier le texte extrait par PDF Miner et extraire uniquement les parties nécessaires afin de ne pas avoir à utiliser l'API Google Translate inutilement. Je vais.
Je pense que Linux avec le système Python3 peut être utilisé. Mon environnement est Cloud9 et Ubuntu 18.04.
pip install pdfminer.six
À propos, PDF Miner est très utile, mais il semble que des caractères déformés soient susceptibles de se produire lorsque vous souhaitez extraire du japonais, etc. Cette fois, je prendrai l'anglais, donc je ne pense pas qu'il y aura des problèmes aussi souvent.
Bogues connus liés à la récupération du japonais dans PDF Miner: J'ai encore des problèmes avec les caractères CID # 39
git clone https://github.com/KanikaniYou/translate_pdf
cd translate_pdf
Structure des fichiers. (Par souci d'explication, j'ai déjà placé 10 fichiers PDF que je souhaite traduire.)
.
├── eng_txt
├── eng_txt_split
├── jpn_txt
├── let_translatable.py
├── pdf_source
│ ├── report_1.pdf
│ ├── report_10.pdf
│ ├── report_2.pdf
│ ├── report_3.pdf
│ ├── report_4.pdf
│ ├── report_5.pdf
│ ├── report_6.pdf
│ ├── report_7.pdf
│ ├── report_8.pdf
│ └── report_9.pdf
├── pdf_to_txt.py
└── translate_en_jp.py
pdf_to_txt.py
import sys
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTContainer, LTTextBox
from pdfminer.pdfinterp import PDFPageInterpreter, PDFResourceManager
from pdfminer.pdfpage import PDFPage
import os
import re
def find_textboxes_recursively(layout_obj):
if isinstance(layout_obj, LTTextBox):
return [layout_obj]
if isinstance(layout_obj, LTContainer):
boxes = []
for child in layout_obj:
boxes.extend(find_textboxes_recursively(child))
return boxes
return[]
def pdf_read_controller(filepath):
try:
text_in_pdf = ""
with open(filepath, 'rb') as f:
for page in PDFPage.get_pages(f):
try:
interpreter.process_page(page)
layout = device.get_result()
boxes = find_textboxes_recursively(layout)
boxes.sort(key=lambda b:(-b.y1, b.x0))
text_in_page = ""
for box in boxes:
text_in_box = ""
text_in_box += box.get_text().strip().strip(" ")
text_in_box.rstrip("\n")
text_in_box = re.sub(r' ', " ", text_in_box)
text_in_page += text_in_box
text_in_pdf += text_in_page
except Exception as e:
print(e)
return(text_in_pdf)
except Exception as e:
print(e)
print("error: " + filepath)
return("no-text")
def make_txtfile(folder_path,file_name,text='error'):
if text != "no-text":
with open(folder_path+"/"+file_name, mode='w') as f:
f.write(text)
laparams = LAParams(detect_vertical=True)
resource_manager = PDFResourceManager()
device = PDFPageAggregator(resource_manager, laparams=laparams)
interpreter = PDFPageInterpreter(resource_manager, device)
if __name__ == '__main__':
for file_name in os.listdir("pdf_source"):
if file_name.endswith(".pdf"):
print(file_name)
text_in_page = pdf_read_controller("pdf_source/" + file_name)
make_txtfile("eng_txt_split",file_name.rstrip("pdf")+"txt",text_in_page)
Lisez tous les fichiers PDF dans le dossier "pdf_source" pour créer un fichier texte et le sortir.
$ python pdf_to_txt.py
report_3.pdf
report_7.pdf
report_2.pdf
report_1.pdf
unpack requires a buffer of 10 bytes
unpack requires a buffer of 8 bytes
report_5.pdf
report_9.pdf
report_8.pdf
unpack requires a buffer of 6 bytes
unpack requires a buffer of 6 bytes
unpack requires a buffer of 4 bytes
report_4.pdf
report_6.pdf
report_10.pdf
J'obtiens des erreurs, mais ignorez-les et créez un fichier texte. Le PDF est déroutant. Erreur similaire: [struct.error: unpack nécessite un argument de chaîne de longueur 16](https://stackoverflow.com/questions/40158637/struct-error-unpack-requires-a-string-argument-of-length -16)
Par exemple, une partie du texte contenait ces parties. Je ne veux pas utiliser l'API Google Translate en vain, alors supprimez les parties dont vous n'avez pas besoin.
let_translatable.py
import os
if __name__ == '__main__':
for file_name in os.listdir("eng_txt_split"):
if file_name.endswith(".txt"):
print(file_name)
text = ""
with open("eng_txt_split/"+file_name) as f:
l = f.readlines()
for line in l:
text += str(line).rstrip('\n')
path_w = "eng_txt/" + file_name
with open(path_w, mode='w') as f:
f.write(text)
Le texte qui apparaît dans PDF Miner est plein de sauts de ligne, et si vous le mettez dans Google Translate tel quel, il ne se traduira pas bien. Par conséquent, créez un nouveau fichier texte sans saut de ligne et exportez-le dans le dossier eng_txt.
$ python let_translatable.py
report_4.txt
report_10.txt
report_2.txt
report_6.txt
report_9.txt
report_5.txt
report_8.txt
report_7.txt
report_3.txt
report_1.txt
Le texte résultant est enfin traduit. Pour le contenu, veuillez vous référer à ce qui précède.
translate_en_jp.py
import requests
import json
import os
import re
import time
API_key = '<Veuillez saisir la clé API ici>'
def post_text(text):
url_items = 'https://www.googleapis.com/language/translate/v2'
item_data = {
'target': 'ja',
'source': 'en',
'q':text
}
response = requests.post('https://www.googleapis.com/language/translate/v2?key={}'.format(API_key), data=item_data)
return response.text
def jsonConversion(jsonStr):
data = json.loads(jsonStr)
return data["data"]["translations"][0]["translatedText"]
def split_text(text):
sen_list = text.split('.')
to_google_sen = ""
from_google = ""
for index, sen in enumerate(sen_list[:-1]):
to_google_sen += sen + '. '
if len(to_google_sen)>1000:
from_google += jsonConversion(post_text(to_google_sen)) +'\n'
time.sleep(1)
to_google_sen = ""
if index == len(sen_list)-2:
from_google += jsonConversion(post_text(to_google_sen))
time.sleep(1)
return from_google
if __name__ == '__main__':
for file_name in os.listdir("eng_txt"):
print("source: " + file_name)
with open("eng_txt/"+file_name) as f:
s = f.read()
new_text = split_text(s)
path_w = "jpn_txt/" + file_name
with open(path_w, mode='w') as f:
f.write(new_text)
$ python translate_en_jp.py
source: report_4.txt
source: report_10.txt
source: report_2.txt
source: report_6.txt
source: report_9.txt
source: report_5.txt
source: report_8.txt
source: report_7.txt
source: report_3.txt
source: report_1.txt
Un long texte prendra un certain temps.
Le fichier texte traduit sera dans le dossier jpn_txt.
Avec cela, vous n'avez pas à vous soucier du PDF anglais! Cependant, le texte produit par cela n'a pas de concept de mise en page, et je pense qu'il peut ne pas être bien traduit entre les pages. À l'origine, ce serait bien si nous pouvions gérer ce domaine, mais cela semble être assez difficile. J'espère que vous pourrez l'utiliser lorsque vous souhaitez lire beaucoup de fichiers PDF en japonais.
Recommended Posts