[PYTHON] Le PDF anglais est traduit en japonais

Je veux traduire des PDF ensemble

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 à

  1. Extrayez le texte du PDF et enregistrez-le sous forme de fichier texte (pdf_to_txt.py)
  2. Formatez le texte et enregistrez-le en tant que nouvelle ligne de fichier texte (let_translatable.py)
  3. Traduisez du texte anglais en japonais et enregistrez-le sous forme de fichier texte (translate_en_jp.py)

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.

environnement

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
スクリーンショット 2019-12-11 15.07.11.png

1. Extraire le texte

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)

1-2. Vérification visuelle du texte (OK sans)

スクリーンショット 2019-12-11 16.34.43.png

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.

2. Formatage du texte

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

3. Traduire de l'anglais vers le japonais!

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.

Livrables

Le fichier texte traduit sera dans le dossier jpn_txt. スクリーンショット 2019-12-11 17.04.05.png

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

Le PDF anglais est traduit en japonais
Pixelliser un PDF avec Python
Sortie japonaise avec Python
J'ai écrit python en japonais
OCR à partir de PDF en Python
Essayez de traduire un PDF anglais, partie 1
Afficher le fichier JSON japonais
Je comprends Python en japonais!
Obtenez des synonymes japonais avec Python
Convertir Markdown en PDF en Python
Rendre matplotlib compatible avec le japonais en 3 minutes
"Dépassement de pile d'exception!"
Comment gérer le japonais avec Python
Comparaison des modules de conversion japonais en Python3
Mettez les polices japonaises dans les images avec Colaboratory
Extraire du texte japonais d'un PDF avec PDFMiner
Sortie PDF en utilisant l'extension Latex avec Sphinx
R: Utilisez le japonais au lieu du japonais dans le script
Gère les caractères japonais UTF-8 dans la base de données MySQL de Python.