

英文のPDFを読み込み、翻訳し、Outlookの下書きとして書き出しをしようと思っています。

(<https://www.cpi-japan.com/services>/ 一番上の「IELTSリーディングサンプル」のPDFファイルを使用)

下記部分でエラーが発生してしまうため、お力添え願いたいです。

[code]

    例外が発生しました: TypeError
    the JSON object must be str, bytes or bytearray, not NoneType
      File "C:\Users\NAME\Documents\練習用\2023_01_rensyuu\test7.py", line 27, in <module>
        result = tr.translate(txt_list, src="en", dest="ja").text
    
[/code]

下記サイトを参考に作成しました。

  * [PythonでPDFを読み込みテキストを抽出する（PyMuPDF）](https://python-work.com/pdf-get-text/)
  * [【Python】gooletransを使って自動翻訳をやってみる。](https://plog.shinmaiblog.com/python-translator/)
  * [PythonでOutlookの指定したアカウントの下に下書きを作る](https://gist.github.com/akilab/529c6954ddbc6024a0e8e2a381126e83)

バージョン：Python 3.9.15

[code]

    #ライブラリ設定
    import fitz # pymupdfライブラリ
    import openpyxl as px 
    from openpyxl.styles import Alignment
    from googletrans import Translator
    import json
     
    #PDFテキストを格納するリスト作成
    txt_list = []
     
    # PDFファイルを読み込む
    filename = 'IELTS.pdf'
    doc = fitz.open(filename)
    
    
    for page in range(len(doc)):
        text = doc[page].get_text()
        text = text.replace('\n', '')
        txt_list.append([page+1,text])
    
    
    #翻訳する
    tr = Translator()
    result = tr.translate(txt_list, src="en", dest="ja").text
    #↑エラー発生個所:print(result)
    
    
    #outlookに下書きを作成
    _VERSION_ = 'v0.1.0'
    def show_version():
        print("=" * 20)
        print("Draft Creater VERSION {}".format(_VERSION_).center(20))
        print("=" * 20)
    
    def main():
        show_version()
        pythoncom.CoInitialize()
        outlook = win32com.client.Dispatch("Outlook.Application")
    
        mapi = outlook.GetNamespace("MAPI")
        # draft_box = mapi.GetDefaultFolder(16) # 16が下書きフォルダの番号らしい
    
        draft_box = mapi.Folders("自分のmailアドレス.co.jp").Folders("下書き")
        mail = outlook.CreateItem(0)
        mail.To = 'to@example.com'
        mail.Subject = 'タイトル'
        mail.HtmlBody = result #←ここに翻訳結果の変数入れたい
        mail.Move(draft_box)
    
    
    if __name__ == '__main__':
        sys.exit(main())
    
[/code]

**試したこと**

JSONで使えないオブジェクトエラーとのことでおそらく文字列型のオブジェクトに変換するのではないかと思い、エラー発生個所の前に下記コードを差し込みましたが例外が発生しました。

[code]

    txt_list = json.loads(txt_list)
    
[/code]

[code]

    TypeError
    the JSON object must be str, bytes or bytearray, not list
      File "C:\Users\NAME\Documents\練習用\2023_01_rensyuu\test7.py", line 24, in <module>
        txt_list = json.loads(txt_list)
    
[/code]

**追記**  
頂いたコメントをもとに修正しました。(1/11)

[code]

    #ライブラリ設定
    import fitz # pymupdfライブラリ
    import openpyxl as px 
    from openpyxl.styles import Alignment
    from googletrans import Translator #**変更箇所**pre-release版(4.0.0-rc1)をインストール
    import json
    import re
    import sys #**変更箇所**追加
     
    #PDFテキストを格納するリスト作成
    txt_list = []
     
    # PDFファイルを読み込む
    filename = 'IELTS.pdf'
    doc = fitz.open(filename)
    
    
    for page in range(len(doc)):
        text = doc[page].get_text()
        text = text.replace('\n', '')
        txt_list.append(text)**#変更箇所・文字列のリストのみにした**
    
    #print(txt_list)
    
    
    #JSON変換
    #txt_list = json.load(txt_list) 
    
    #翻訳する
    tr = Translator()
    try:
        for pagetext in txt_list:
            # 1ページ分が１つの文字列で、それを日本語に翻訳
            result = tr.translate(pagetext, src="en", dest="ja").text
            #print(result) #★**ここでprintした場合の結果は以下参照**
    except Exception as e:
        print(e)
    
    """ 
    tr = Translator()
    result = tr.translate(txt_list, src="en", dest="ja") 
    for results in result:
        print(results.origin, ' -> ', results.text)
    """
    
    
    #outlookに下書きを作成
    _VERSION_ = 'v0.1.0'
    def show_version():
        print("=" * 20)
        print("Draft Creater VERSION {}".format(_VERSION_).center(20))
        print("=" * 20)
    
    
    def main():
        show_version()
        pythoncom.CoInitialize() #**エラー発生個所**
        outlook = win32com.client.Dispatch("Outlook.Application")
    
        mapi = outlook.GetNamespace("MAPI")
        # draft_box = mapi.GetDefaultFolder(16) # 16が下書きフォルダの番号らしい
    
        draft_box = mapi.Folders("自分のメールアドレスco.jp").Folders("下書き")
        mail = outlook.CreateItem(0)
        mail.To = 'to@example.com'
        mail.Subject = 'タイトル'
        mail.HtmlBody = result
        mail.Move(draft_box)
    
    
    if __name__ == '__main__':
        sys.exit(main())
    
    
[/code]

**上記コード内のエラー発生個所のエラーメッセージ**

[code]

    例外が発生しました: NameError
    name 'pythoncom' is not defined
      File "C:\Users\NAME\Documents\練習用\2023_01_rensyuu\test7.py", line 68, in main
        pythoncom.CoInitialize()
      File "C:\Users\NAME\Documents\練習用\2023_01_rensyuu\test7.py", line 83, in <module>
        sys.exit(main())
    
[/code]

**上記コード内★部分のprint結果**  
ターミナルに表示されたものをwordに貼り付けて確認したが、  
約２５文字ごとに改行がされているので改行なしのべた打ちにしたい。

[code]

    CPI IELTS SAMPLES READING PASSING 1 PASSING 1に
    は、1950年代のエチオピアでテレビ放映された陸上 
    競技の出現以来、エチオピアの長年の成功以下のパ 
    (文字数4039字のため省略)
    
[/code]


CC BY-SA 4.0
2023-01-10T06:39:47.413
93284
2023-01-11T12:11:47.823
2023-01-11T11:55:48.737
56378
56378
question
python python3 pdf
pythonでJSONエラーのTypeError: the JSON object must be str, bytes or bytearray


内容的には自身で参照している以下の記事の内容を変更しようとして上手くいかなかった、ということでしょう。  
[【Python】gooletransを使って自動翻訳をやってみる。](https://plog.shinmaiblog.com/python-
translator/)  
こちらの記事では googletrans に翻訳依頼するテキストをリスト等ではなく単一の文字列で指定しています。

それに対して質問のソースコードでは、おそらく高速化を意図したのでしょうが、文字列のリスト(当初は「「数値と文字列のリスト」のリスト」)を渡しています。  
当初：「数値と文字列のリスト」のリスト

[code]

        txt_list.append([page+1,text])
    
[/code]

変更：文字列のリスト

[code]

        txt_list.append(text) #**変更箇所・文字列のリストのみにした**
    
[/code]

* * *

そして安定版の最新(3.0.0)のドキュメントでは、以下のように文字列のリストもパラメータに指定出来ていたのでしょうが：  
[translate(text, dest='en', src='auto', **kwargs)](https://py-
googletrans.readthedocs.io/en/latest/#googletrans.Translator.translate)

>   * text (UTF-8 str; unicode; string sequence (list, tuple, iterator,
> generator)) – The source text(s) to be translated. Batch translation is
> supported via sequence input.
>

質問のソース(変更中のもの)

[code]

    tr = Translator()
    result = tr.translate(txt_list, src="en", dest="ja") #**エラー発生個所**
    
[/code]

冒頭の記事やコメントで紹介した以下の記事にあるように安定版の最新(3.0.0)にはバグ(仕様変更？)があってpre-
release版(4.0.0-rc1)を使う必要があるのでしょう。  
[googletrans でエラーが出た場合は PRE-RELEASE で回避可能](https://sig9.org/archives/4023)

そしてどうもpre-
release版(4.0.0-rc1)では文字列のリストをサポートしておらず、翻訳依頼するテキストを単一の文字列で指定する必要があるようです。  
冒頭の記事や質問者さん自身の途中のコメントにあるように、以下のような形で出来るでしょう。`print(result)`の部分はoutlookに渡すためのデータ作成にする必要がありますが。

[code]

    tr = Translator()
    try:
        for pagetext in txt_list:
            # 1ページ分が１つの文字列で、それを日本語に翻訳
            result = tr.translate(pagetext, src="en", dest="ja").text
            print(result)
    except Exception as e:
        print(e)
    
[/code]

* * *

ちなみにコメントで「今度は最終行の sys.exit(main())に例外が発生しました: NameError name 'sys' is not
defined」となっていた部分は、それに対応する`import sys`が行われていないためですね。

* * *

**追記に対応して：**

NameError name 'pythoncom' is not definedエラーについては NameError name 'sys' is not
definedと同様に、必要なimportが不足しているからですね。  
参照している3つ目の記事に書かれているimportを同様に組み込んでください。  
[PythonでOutlookの指定したアカウントの下に下書きを作る](https://gist.github.com/akilab/529c6954ddbc6024a0e8e2a381126e83)

Wordに貼り付けたテキストが約25文字で改行される件は、Word文書のページ書式がそうなっているのでは？
例えばメモ帳とかテキストエディタの編集画面に貼り付けたならそうしたことにはならないでしょう。

そしてそれは当初の質問内容とは違ったものになっているので、必要ならば新たな質問として記事を立ててください。


CC BY-SA 4.0
2023-01-10T13:44:18.807
93291
2023-01-11T12:11:47.823
2023-01-11T12:11:47.823
26370
26370
93284
answer