سؤال

للعمل مع MS word الملفات في بيثون ، هناك بيثون win32 امتداد ، والتي يمكن استخدامها في نظام التشغيل windows.كيف أفعل نفس الشيء في لينكس ؟ هل هناك أي مكتبة ؟

هل كانت مفيدة؟

المحلول

هل يمكن أن تجعل subprocess الدعوة إلى antiword.Antiword هو لينكس سطر الأوامر أداة الإغراق نص من مستند word.يعمل بشكل جيد جدا بسيطة الوثائق (من الواضح أنه يفقد التنسيق).انها متوفرة من خلال apt, وربما دورة في الدقيقة ، أو يمكنك تجميع نفسك.

نصائح أخرى

استخدام الأم بيثون وحدة docx.هنا كيفية استخراج كل نص من مستند:

document = docx.Document(filename)
docText = '\n\n'.join([
    paragraph.text.encode('utf-8') for paragraph in document.paragraphs
])
print docText

انظر بيثون DocX الموقع

تحقق أيضا Textract والتي تسحب الجداول الخ.

XML مع regexs استدعاء "كاتولو".لا تفعل ذلك!

بنيامين's الجواب هو جيد.لقد الموحدة...

import zipfile, re

docx = zipfile.ZipFile('/path/to/file/mydocument.docx')
content = docx.read('word/document.xml').decode('utf-8')
cleaned = re.sub('<(.|\n)*?>','',content)
print(cleaned)

OpenOffice.org يمكن كتابتها مع بيثون: انظر هنا.

منذ OOo يمكن تحميل معظم MS Word ملفات لا تشوبه شائبة ، أود أن أقول هذا هو أفضل رهان.

أعرف أن هذا هو السؤال القديم, ولكن كنت مؤخرا في محاولة لايجاد وسيلة لاستخراج النص من MS word وملفات أفضل حل حتى الآن وجدت مع wvLib:

http://wvware.sourceforge.net/

بعد تثبيت المكتبة استخدامه في بيثون هي سهلة جدا:

import commands

exe = 'wvText ' + word_file + ' ' + output_txt_file
out = commands.getoutput(exe)
exe = 'cat ' + output_txt_file
out = commands.getoutput(exe)

و هذا الأمر.كثيرا ما نقوم به هو استخدام الأوامر.getouput وظيفة لتشغيل بعض البرامج النصية قذيفة ، وهي wvText (الذي يستخرج نص من مستند Word و القط قراءة الملف الناتج).بعد ذلك كامل النص من مستند Word سوف يكون في متغير, جاهزة للاستخدام.

نأمل أن هذا سوف يساعد أي شخص وجود قضايا مماثلة في المستقبل.

نلقي نظرة على كيف doc يعمل و إنشاء مستند word باستخدام PHP في لينكس.السابق هو مفيدة بشكل خاص. Abiword هو أداة الموصى بها.هناك القيود على الرغم من:

ومع ذلك ، إذا كان المستند يحتوي معقدة الجداول مربعات النص جزءا لا يتجزأ من جداول البيانات ، وما إلى ذلك ، فإنه قد لا تعمل كما هو متوقع.النامية جيدة MS Word المرشحات هو عملية صعبة جدا ، لذا يرجى تتحمل معنا ونحن نعمل على الحصول على مستندات Word لفتح بشكل صحيح.إذا كان لديك مستند Word الذي فشل تحميل, يرجى فتح علة وتشمل الوثيقة حتى نتمكن من تحسين المستورد.

(ملاحظة:لقد نشرت هذا على هذا السؤال فضلا, ولكن يبدو ذات الصلة هنا ، لذا يرجى عذر بعد ثانية.)

الآن, هذا هو قبيح جدا و جميلة hacky, ولكن يبدو أن العمل بالنسبة لي الأساسية استخراج النص.ومن الواضح أن استخدام هذا في Qt البرنامج يجب أن تفرخ عملية لذلك الخ ، ولكن سطر الأوامر لقد اخترق معا هو:

unzip -p file.docx | grep '<w:t' | sed 's/<[^<]*>//g' | grep -v '^[[:space:]]*$'

لذلك هذا هو:

بفك -p file.docx:-p == "بفك إلى المعياري"

grep ':انتزاع فقط الخطوط التي تحتوي على '<w:t' (<w:t=""> هو Word 2007 عنصر XML "النص" ، بقدر ما يمكنني أن أقول)

sed 's/<[^<]>//g'*:إزالة كل شيء داخل الكلمات

grep -v '^[[:space:]]$'*:إزالة الأسطر الفارغة

يرجح أن هناك وسيلة أكثر كفاءة للقيام بذلك ، ولكن يبدو أن العمل بالنسبة لي على بعض المستندات لقد اختبرت ذلك مع.

بقدر ما أنا على علم, بفك, البقرى و sed جميع موانئ ويندوز أي من Unixes ، لذلك يجب أن تكون معقولة عبر منصة.Despit يجري قليلا من الإختراق القبيح ;)

إذا كان القصد هو استخدام بحتة وحدات بيثون دون استدعاء subprocess ، يمكنك استخدام zipfile الثعبان modude.

content = ""
# Load DocX into zipfile
docx = zipfile.ZipFile('/home/whateverdocument.docx')
# Unpack zipfile
unpacked = docx.infolist()
# Find the /word/document.xml file in the package and assign it to variable
for item in unpacked:
    if item.orig_filename == 'word/document.xml':
        content = docx.read(item.orig_filename)

    else:
        pass

المحتوى الخاص بك سلسلة ومع ذلك يحتاج إلى تنظيف ، طريقة واحدة للقيام بذلك هو:

# Clean the content string from xml tags for better search
fullyclean = []
halfclean = content.split('<')
for item in halfclean:
    if '>' in item:
        bad_good = item.split('>')
        if bad_good[-1] != '':
            fullyclean.append(bad_good[-1])
        else:
            pass
    else:
        pass

# Assemble a new string with all pure content
content = " ".join(fullyclean)

ولكن هناك بالتأكيد أكثر أناقة طريقة لتنظيف السلسلة, ربما باستخدام إعادة الوحدة.ويساعد هذا الأمل.

Unoconv قد يكون أيضا بديلا جيدا: http://linux.die.net/man/1/unoconv

إذا كان لديك تثبيت ليبر أوفيس, يمكنك ببساطة استدعاء من سطر الأوامر إلى تحويل الملف إلى النص, ثم تحميل النص في بيثون.

لست متأكدا إذا كنت ستكون لدينا الكثير من الحظ دون استخدام COM.على .doc يبعث على السخرية معقدة و غالبا ما تسمى "تفريغ الذاكرة" من كلمة في وقت إنقاذ!

في سواتي في HTML ، التي على ما يرام ومدهش ، ولكن معظم مستندات word ليست لطيفة جدا!

قراءة Word 2007 و في وقت لاحق الملفات, بما في ذلك .ملفات docx, يمكنك استخدام بيثون-docx الحزمة:

from docx import Document
document = Document('existing-document-file.docx')
document.save('new-file-name.docx')

إلى قراءة .دكتور الملفات من Word 2003 وفي وقت سابق ، وجعل subprocess الدعوة إلى antiword.تحتاج إلى تثبيت antiword الأولى:

sudo apt-get install antiword

ثم مجرد دعوة من بيثون السيناريو:

import os
input_word_file = "input_file.doc"
output_text_file = "output_file.txt"
os.system('antiword %s > %s' % (input_word_file, output_text_file))

هذا قديم السؤال ؟ وأعتقد أن هذا الشيء غير موجود.هناك فقط أجاب إجابة منها.هذا هو واحد جميلة لم يتم الرد عليها ، أو نصف الإجابة إذا كنت ترغب في ذلك.حسنا, طرق القراءة *.docx (MS Word 2007 وما بعدها) الوثائق دون استخدام interop COM كلها مغطاة.ولكن طرق استخراج النص من *.doc (MS Word 97-2000) ، وذلك باستخدام بيثون فقط ، يفتقر.هذا التعقيد ؟ القيام به:ليس حقا أن نفهم:حسنا, هذا شيء آخر.

عندما لم أجد أي الانتهاء من التعليمات البرمجية, أنا قرأت بعض مواصفات تنسيق و حفرت بعض الخوارزميات المقترحة في اللغات الأخرى.

MS Word (*.doc) الملف OLE2 مجمع الملف.لا يزعجك مع الكثير من التفاصيل غير الضرورية ، كما أنها تفكر في نظام الملفات المخزنة في ملف.فإنه في الواقع يستخدم الدهون البنية ، ذلك التعريف يحمل.(Hm, ربما يمكنك حلقة جبل في لينكس???) بهذه الطريقة, يمكنك تخزين المزيد من الملفات في ملف مثل الصور وغيرها.وفعلت الشيء نفسه في *.docx باستخدام أرشيف مضغوط بدلا من ذلك.تتوفر حزم على PyPI التي يمكن قراءة ملفات OLE.مثل (olefile, compoundfiles, ...) اعتدت compoundfiles حزمة مفتوحة *.ملف doc.ومع ذلك ، في MS Word 97-2000 الداخلية subfiles لا XML أو HTML ، ولكن الملفات الثنائية.و مثل هذا لا يكفي ، يحتوي على كل المعلومات عن الآخر لذا يجب أن تقرأ على الأقل اثنين منهم وكشف تخزين معلومات وفقا لذلك.أن نفهم تماما ، قراءة وثيقة PDF التي أخذت الخوارزمية.

رمز أدناه جدا على عجل تتألف واختبارها على عدد قليل من الملفات.بقدر ما أستطيع أن أرى ، فإنه يعمل على النحو المنشود.أحيانا بعض رطانة يظهر في البداية و دائما تقريبا في نهاية النص.ويمكن أن يكون هناك بعض شخصيات غريبة في بين كذلك.

أولئك منكم الذين يرغبون في البحث عن النص سوف تكون سعيدة.لا يزال, وأحث أي شخص يمكن أن تساعد على تحسين هذا القانون للقيام بذلك.


doc2text module:
"""
This is Python implementation of C# algorithm proposed in:
http://b2xtranslator.sourceforge.net/howtos/How_to_retrieve_text_from_a_binary_doc_file.pdf

Python implementation author is Dalen Bernaca.
Code needs refining and probably bug fixing!
As I am not a C# expert I would like some code rechecks by one.
Parts of which I am uncertain are:
    * Did the author of original algorithm used uint32 and int32 when unpacking correctly?
      I copied each occurence as in original algo.
    * Is the FIB length for MS Word 97 1472 bytes as in MS Word 2000, and would it make any difference if it is not?
    * Did I interpret each C# command correctly?
      I think I did!
"""

from compoundfiles import CompoundFileReader, CompoundFileError
from struct import unpack

__all__ = ["doc2text"]

def doc2text (path):
    text = u""
    cr = CompoundFileReader(path)
    # Load WordDocument stream:
    try:
        f = cr.open("WordDocument")
        doc = f.read()
        f.close()
    except: cr.close(); raise CompoundFileError, "The file is corrupted or it is not a Word document at all."
    # Extract file information block and piece table stream informations from it:
    fib = doc[:1472]
    fcClx  = unpack("L", fib[0x01a2l:0x01a6l])[0]
    lcbClx = unpack("L", fib[0x01a6l:0x01a6+4l])[0]
    tableFlag = unpack("L", fib[0x000al:0x000al+4l])[0] & 0x0200l == 0x0200l
    tableName = ("0Table", "1Table")[tableFlag]
    # Load piece table stream:
    try:
        f = cr.open(tableName)
        table = f.read()
        f.close()
    except: cr.close(); raise CompoundFileError, "The file is corrupt. '%s' piece table stream is missing." % tableName
    cr.close()
    # Find piece table inside a table stream:
    clx = table[fcClx:fcClx+lcbClx]
    pos = 0
    pieceTable = ""
    lcbPieceTable = 0
    while True:
        if clx[pos]=="\x02":
            # This is piece table, we store it:
            lcbPieceTable = unpack("l", clx[pos+1:pos+5])[0]
            pieceTable = clx[pos+5:pos+5+lcbPieceTable]
            break
        elif clx[pos]=="\x01":
            # This is beggining of some other substructure, we skip it:
            pos = pos+1+1+ord(clx[pos+1])
        else: break
    if not pieceTable: raise CompoundFileError, "The file is corrupt. Cannot locate a piece table."
    # Read info from pieceTable, about each piece and extract it from WordDocument stream:
    pieceCount = (lcbPieceTable-4)/12
    for x in xrange(pieceCount):
        cpStart = unpack("l", pieceTable[x*4:x*4+4])[0]
        cpEnd   = unpack("l", pieceTable[(x+1)*4:(x+1)*4+4])[0]
        ofsetDescriptor = ((pieceCount+1)*4)+(x*8)
        pieceDescriptor = pieceTable[ofsetDescriptor:ofsetDescriptor+8]
        fcValue = unpack("L", pieceDescriptor[2:6])[0]
        isANSII = (fcValue & 0x40000000) == 0x40000000
        fc      = fcValue & 0xbfffffff
        cb = cpEnd-cpStart
        enc = ("utf-16", "cp1252")[isANSII]
        cb = (cb*2, cb)[isANSII]
        text += doc[fc:fc+cb].decode(enc, "ignore")
    return "\n".join(text.splitlines())

مجرد خيار للقراءة 'doc' الملفات دون استخدام COM: miette.يجب أن تعمل على أي منصة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top