PDFをテキストに変換するPythonモジュール[終了]


385

PDFファイルをテキストに変換するPythonモジュールはありますか?pypdfを使用するActivestateで見つかったコードの1つを試してみましたが、生成されたテキストの間にスペースがなく、役に立ちませんでした。


1
私は同様の解決策を探していました。PDFファイルからテキストを読み取るだけです。画像は必要ありません。pdfminerは良い選択ですが、テキストを抽出する方法の簡単な例は見つかりませんでした。最後に私はこのSO回答(stackoverflow.com/questions/5725278/…)を取得し、現在それを使用しています。
Nayan

2
質問が終了したので、誰かが新しい回答を書きたい場合に備えて、ソフトウェアの推奨事項に特化したStack Exchangeに再
投稿しました。PDF

1
UTF-8コンテンツに対して私のために機能した唯一のソリューション:Apache Tika
Shoham

PythonでのPDFからテキストへの変換に使用できるオプションのリストを更新したい。GroupDocs.ConversionPython用のCloud SDKは、 PDFをテキストに正確に変換します。
Tilal Ahmad

回答:


142

PDFMinerをお試しください。HTML、SGMLまたは「タグ付きPDF」形式としてPDFファイルからテキストを抽出できます。

タグ付きPDF形式は最もクリーンなようで、XMLタグを削除すると、テキストのみが残ります。

Python 3バージョンは次の場所にあります。


2
ライブラリとしてpdfminerを使用する方法を説明する回答を追加しました。
codeape、2008年

24
Python 3のサポートなし:(
Karl Adler

1
このスレッドで提供した答えは、この答えを見て、ライブラリの使用方法を知りたい人にとって役立つかもしれません。PDFMinerライブラリを使用してPDFからテキストを抽出する方法の例を示します。ドキュメンテーションは少し疎いので、私はそれが何人かの人々を助けるかもしれないと考えました。
DuckPuncher、2015

17
Python 3に関しては、6ベースのフォークpypi.python.org/pypi/pdfminer.sixがあります
Denis Cornehl


136

PDFMinerのため、パッケージが変更されましたcodeapeを掲載しました。

編集(もう一度):

PDFMinerがバージョンで再度更新されました 20100213

インストールしたバージョンは、次の方法で確認できます。

>>> import pdfminer
>>> pdfminer.__version__
'20100213'

これが更新されたバージョンです(私が変更/追加したものについてのコメント付き):

def pdf_to_csv(filename):
    from cStringIO import StringIO  #<-- added so you can copy/paste this to try it
    from pdfminer.converter import LTTextItem, TextConverter
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, LTTextItem):
                    (_,_,x,y) = child.bbox                   #<-- changed
                    line = lines[int(-y)]
                    line[x] = child.text.encode(self.codec)  #<-- changed

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec="utf-8")  #<-- changed 
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       #<-- changed
    parser.set_document(doc)     #<-- added
    doc.set_parser(parser)       #<-- added
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

編集(まだまだ):

ここでは、最新バージョンのアップデートでは、PyPIは20100619p1。要するに、私は交換しLTTextItemLTCharとCsvConverterコンストラクタにLAParamsのインスタンスを通過しました。

def pdf_to_csv(filename):
    from cStringIO import StringIO  
    from pdfminer.converter import LTChar, TextConverter    #<-- changed
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, LTChar):               #<-- changed
                    (_,_,x,y) = child.bbox                   
                    line = lines[int(-y)]
                    line[x] = child.text.encode(self.codec)

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec="utf-8", laparams=LAParams())  #<-- changed
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       
    parser.set_document(doc)     
    doc.set_parser(parser)       
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        if page is not None:
            interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

編集(もう一度):

バージョン用に更新20110515(Oeufcoque Penteanoに感謝!):

def pdf_to_csv(filename):
    from cStringIO import StringIO  
    from pdfminer.converter import LTChar, TextConverter
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item._objs:                #<-- changed
                if isinstance(child, LTChar):
                    (_,_,x,y) = child.bbox                   
                    line = lines[int(-y)]
                    line[x] = child._text.encode(self.codec) #<-- changed

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec="utf-8", laparams=LAParams())
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       
    parser.set_document(doc)     
    doc.set_parser(parser)       
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        if page is not None:
            interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

1
[6]内:pdfminerをインポート[7]:pdfminer .__ version__ Out [7]: '20100424' In [8]:from pdfminer.converter import LTTextItem ImportError:cannot import name LTTextItem .... LITERALS_DCT_DECODE LTChar LTImage LTPolygon LTTextBox LITERAL_DEVICE_GRAY LTContainer LTLine LTRect LTTextGroup LITERAL_DEVICE_RGB LTFigure LTPage LTText LTTextLine
Skylar Saveland 2010

@skyl、上記のコードは以前のバージョン '20100213'用です。彼らのウェブサイトの変更リストから、彼らはに変更されたLTTextItemようLTCharです。 unixuser.org/~euske/python/pdfminer/index.html#changes
tgray 2010

2
@Oeufcoque Penteano、ありがとう!20110515コメントごとにバージョンの回答に別のセクションを追加しました。
tgray 2013年

1
@ user3272884の回答は2014
jmunsch

1
私は今日、同じ問題を解決する必要がありました。空白に関する情報を抽出するためにtgrayのコードを少し変更し、ここ
tarikki

67

これらのソリューションはいずれも最新バージョンのPDFMinerをサポートしていないため、PDFMinerを使用してPDFのテキストを返す簡単なソリューションを作成しました。これは、インポートエラーが発生している人のために機能しますprocess_pdf

import sys
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
from pdfminer.layout import LAParams
from cStringIO import StringIO

def pdfparser(data):

    fp = file(data, 'rb')
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.

    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        data =  retstr.getvalue()

    print data

if __name__ == '__main__':
    pdfparser(sys.argv[1])  

Python 3で機能する以下のコードを参照してください。

import sys
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
from pdfminer.layout import LAParams
import io

def pdfparser(data):

    fp = open(data, 'rb')
    rsrcmgr = PDFResourceManager()
    retstr = io.StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.

    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        data =  retstr.getvalue()

    print(data)

if __name__ == '__main__':
    pdfparser(sys.argv[1])  

2
これは私が見つけた最初のスニペットで、実際には奇妙なPDFファイルで動作します(特に、packtpubから入手できる無料の電子ブック)。他のすべてのコードは、奇妙にエンコードされた生のものを返すだけですが、実際のコードはテキストを返します。ありがとう!
somada141

データを取得した後、おそらくretstr.seek(0)を実行する必要があります。そうしないと、すべてのページからテキストが蓄積されます。
Tshirtman

2
で使用するにはpython3、後に明らかに括弧以外にprint交換するコマンド、1が持っているfileと、コマンドをopenし、インポートStringIOパッケージからio
McLawrence

1
ワオ。このブロックは、初めてコピーしたときに完全に機能しました。データの解析と修正を行い、データの入力にストレスをかける必要はありません。
SecsAndCyber​​ 2017

1
pdfminerはpython3では機能しません。このコードはpdfminer3kのために仕事をしません
タン

47

Pdftotextオープンソースプログラム(Xpdfの一部)で、Pythonから呼び出すことができます(要求したものではありませんが、役に立つ場合があります)。問題なく使用しました。私はグーグルがグーグルデスクトップでそれを使用すると思います。


6
これ-layoutは、PDFと同じ位置にテキストを保持するオプションがあるため、ここにリストされているツールの中で最も便利なようです。ここで、PDFのコンテンツをそれにパイプする方法を理解できたとしたら。
Matthew Schinckel、2012年

いくつかのソリューションをテストした後、これは最も単純で最も堅牢なオプションのようです。一時ファイルを使用して出力を書き込む場所を指示するPythonで簡単にラップできます。
セリン

Cerin、出力をstdoutにリダイレクトするファイル名として「-」を使用します。このように、単純なsubprocess.check_outputを使用すると、この呼び出しは内部関数のように感じられます。
Ctrl-C

それを使用している人を強化するためだけに。。。pdftotext非常にうまく機能しているようですが、標準出力で結果を表示するには、ハイフンである2番目の引数が必要です。
ゴードンリノフ2015年

1
これfind . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;により、現在のフォルダーから始まるすべてのPDFファイルが再帰的に変換されます。デフォルトでは、生成されたファイルには元の名前に.txt拡張子が付いています。
ccpizza

43

pyPDFは正常に動作します(整形式のPDFで作業していると想定しています)。必要なのがテキスト(スペースを含む)だけの場合は、次のようにします。

import pyPdf
pdf = pyPdf.PdfFileReader(open(filename, "rb"))
for page in pdf.pages:
    print page.extractText()

また、メタデータや画像データなどに簡単にアクセスできます。

extractTextコードノートのコメント:

すべてのテキスト描画コマンドを、コンテンツストリームで提供される順序で見つけ、テキストを抽出します。これは、使用するジェネレーターによっては、一部のPDFファイルではうまく機能しますが、他のファイルではうまく機能しません。これは将来的に改良されます。この関数から出てくるテキストの順序に依存しないでください。この関数がより洗練されたものになると変更されるためです。

これが問題であるかどうかは、テキストで何をしているのかに依存します(たとえば、順序が重要でない場合は問題ありません。ジェネレータがテキストを表示される順序でストリームに追加する場合は問題ありません) 。私は問題なくpyPdf抽出コードを日常的に使用しています。


7
Unicodeサポートなし:(
PanosJee

7
pyPdfは現在UTFをサポートしています。
lbolla '18年

2
このライブラリはゴミのように見えます。ランダムPDFでテストすると、エラー「pyPdf.utils.PdfReadError:EOFマーカーが見つかりません」
Cerin

4
質問から:生成されたテキストの間にスペースがなく、役に立たなかった。私はpyPDFを使用して同じ結果を得ました-単語の間にスペースがないテキストが抽出されます。
ジョーダンライター

page.extractText()関数を実行すると、「TypeError:Ca n't convert 'bytes' object to str implicitly」というエラーが表示されます。どうすれば対処できますか?
juankysmith 2013

21

ライブラリとしてpdfminerを非常に簡単に使用することもできます。PDFのコンテンツモデルにアクセスでき、独自のテキスト抽出を作成できます。以下のコードを使用して、pdfコンテンツをセミコロンで区切られたテキストに変換するためにこれを行いました。

この関数は、単純にTextItemコンテンツオブジェクトをy座標とx座標に従って並べ替え、同じy座標を持つアイテムを1つのテキスト行として出力し、同じ行のオブジェクトを「;」で区切ります。文字。

このアプローチを使用して、PDFからテキストを抽出することができましたが、他のツールではそれ以上の解析に適したコンテンツを抽出できませんでした。私が試した他のツールには、pdftotext、ps2ascii、オンラインツールpdftextonline.comなどがあります。

pdfminerは、pdfスクレイピングに欠かせないツールです。


def pdf_to_csv(filename):
    from pdflib.page import TextItem, TextConverter
    from pdflib.pdfparser import PDFDocument, PDFParser
    from pdflib.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, TextItem):
                    (_,_,x,y) = child.bbox
                    line = lines[int(-y)]
                    line[x] = child.text

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, "ascii")

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(doc, fp)
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

更新

上記のコードは古いバージョンのAPIに対して作成されています。以下のコメントを参照してください。


メイトを動作させるには、どのようなプラグインが必要ですか?私は...ダウンロードしてインストールpdfminerが、それは十分ではありません
KXK

1
上記のコードは、古いバージョンのPDFminerに対して作成されています。APIは最近のバージョンで変更されました(たとえば、パッケージはになりましたがpdfminer、ではなくなりましたpdflib)。pdf2txt.pyPDFminerソースのソースを確認することをお勧めします。上記のコードは、そのファイルの古いバージョンに触発されたものです。
codeape

17

slate ライブラリからPDFMinerを使用することを非常に簡単にするプロジェクトです。

>>> with open('example.pdf') as f:
...    doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'   

1
{ファイルを"C:\ Python33 \ libに\のsite-packages \スレート-0.3-py3.3.egg \ slate_ "輸入スレート"を実行しながら、私は、インポートエラーを取得していますinit_の.py"、48行、で、<モジュール> ImportError:名前PDFをインポートできません}しかし、PDFクラスがあります!これを解決する方法を知っていますか?
juankysmith 2013

いいえ、これは非常に奇妙に聞こえます。依存関係はありますか?
Tim McNamara

通常、私逃したの依存性に関するメッセージを取得し、この場合には、私が得る古典的なメッセージ「インポートスレートファイル"C:\ Python33 \ libに\のsite-packages \スレート-0.3-py3.3.egg \ slate_ init_の.py"、ライン48 、<モジュール>のImportError:名前PDFをインポートできません "
juankysmith


6
このパッケージはもう保守されていません。使用はご遠慮ください。Python 3.5では使用できません
Sivasubramaniam Arunachalam 2017

9

Pythonモジュール内で特定のPDFをプレーンテキストに変換する必要がありました。PDFMiner 20110515 を使用しました。pdf2txt.pyツールを読んだ後、次の簡単なスニペットを作成しました。

from cStringIO import StringIO
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams

def to_txt(pdf_path):
    input_ = file(pdf_path, 'rb')
    output = StringIO()

    manager = PDFResourceManager()
    converter = TextConverter(manager, output, laparams=LAParams())
    process_pdf(manager, converter, input_)

    return output.getvalue() 

1
デフto_txt(pdf_path):
カタリンジョージFeştilă

特定の数のページのみを変換したい場合、このコードでどうすればよいですか?
psychok7 14

@ psychok7 pdf2txtツールを使用してみましたか?実装が続くやすいようで、あまりにもカスタマイズすることが容易であるべきである、-pフラグと現在のバージョンではその機能をサポートするようだ: github.com/euske/pdfminer/blob/master/tools/pdf2txt.py希望それは役立ちます!:)
gonz

1
thanx @gonz、私は上記のすべてを試しましたが、あなたの解決策は私にとって完璧であることが
わかりました

pdf2txt.pyは私のためにここにインストールされています:C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
赤エンドウ

6

pdfminerに付属するpdf2txt.pyコードを転用します。PDFへのパスを取得する関数を作成できます。オプションで、outtype(txt | html | xml | tag)およびコマンドラインpdf2txt {'-o': '/path/to/outfile.txt' ...}のように選択します。デフォルトでは、以下を呼び出すことができます。

convert_pdf(path)

テキストファイルが作成されます。これは、ファイルシステムの元のPDFの兄弟です。

def convert_pdf(path, outtype='txt', opts={}):
    import sys
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf
    from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter, TagExtractor
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfdevice import PDFDevice
    from pdfminer.cmapdb import CMapDB

    outfile = path[:-3] + outtype
    outdir = '/'.join(path.split('/')[:-1])

    debug = 0
    # input option
    password = ''
    pagenos = set()
    maxpages = 0
    # output option
    codec = 'utf-8'
    pageno = 1
    scale = 1
    showpageno = True
    laparams = LAParams()
    for (k, v) in opts:
        if k == '-d': debug += 1
        elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') )
        elif k == '-m': maxpages = int(v)
        elif k == '-P': password = v
        elif k == '-o': outfile = v
        elif k == '-n': laparams = None
        elif k == '-A': laparams.all_texts = True
        elif k == '-D': laparams.writing_mode = v
        elif k == '-M': laparams.char_margin = float(v)
        elif k == '-L': laparams.line_margin = float(v)
        elif k == '-W': laparams.word_margin = float(v)
        elif k == '-O': outdir = v
        elif k == '-t': outtype = v
        elif k == '-c': codec = v
        elif k == '-s': scale = float(v)
    #
    CMapDB.debug = debug
    PDFResourceManager.debug = debug
    PDFDocument.debug = debug
    PDFParser.debug = debug
    PDFPageInterpreter.debug = debug
    PDFDevice.debug = debug
    #
    rsrcmgr = PDFResourceManager()
    if not outtype:
        outtype = 'txt'
        if outfile:
            if outfile.endswith('.htm') or outfile.endswith('.html'):
                outtype = 'html'
            elif outfile.endswith('.xml'):
                outtype = 'xml'
            elif outfile.endswith('.tag'):
                outtype = 'tag'
    if outfile:
        outfp = file(outfile, 'w')
    else:
        outfp = sys.stdout
    if outtype == 'txt':
        device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams)
    elif outtype == 'xml':
        device = XMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, outdir=outdir)
    elif outtype == 'html':
        device = HTMLConverter(rsrcmgr, outfp, codec=codec, scale=scale, laparams=laparams, outdir=outdir)
    elif outtype == 'tag':
        device = TagExtractor(rsrcmgr, outfp, codec=codec)
    else:
        return usage()

    fp = file(path, 'rb')
    process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password)
    fp.close()
    device.close()

    outfp.close()
    return

1

PDFminerは、私が試したpdfファイルのすべてのページにおそらく1行[7ページの1ページ目...]を与えてくれました。

私がこれまでに得た最良の答えは、pdftoipe、またはそれがXpdfに基づいているc ++コードです。

pdftoipeの出力がどのように見えるかについては、私の質問を参照しください。



1

私は引数pdftohtmlとともに使用し、-xml結果をで読み取りました。これにより、PDF内のsubprocess.Popen()すべてのテキストスニペットのx座標、y座標、幅、高さ、およびフォントが得られます。同じエラーメッセージが出力されるため、「evince」もおそらくこれを使用していると思います。

柱状データを処理する必要がある場合は、PDFファイルに適したアルゴリズムを発明する必要があるため、少し複雑になります。問題は、PDFファイルを作成するプログラムが、必ずしもテキストを論理的な形式でレイアウトするとは限らないことです。単純なソートアルゴリズムを試すこともできますが、時々機能しますが、「ストラグラー」や「ストレイ」など、思い通りの順序で配置されないテキストが存在する可能性があります。だからあなたは創造的になる必要があります。

私が取り組んでいるPDFの1つを見つけるのに約5時間かかりました。しかし、今はかなりうまくいきます。幸運を。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.