【问题标题】:Removing personal information from the comments in a word file using python使用python从word文件中的评论中删除个人信息
【发布时间】:2016-06-23 01:27:40
【问题描述】:

我想从一个 word 文件中的 cmets 中删除所有个人信息。

删除作者姓名很好,我使用以下方法做到了,

document = Document('sampleFile.docx')
core_properties = document.core_properties
core_properties.author = ""
document.save('new-filename.docx')

但这不是我需要的,我想删除在该 word 文件中发表评论的任何人的姓名。

我们手动执行此操作的方式是进入首选项->安全性->保存时从此文件中删除个人信息

【问题讨论】:

  • 我没有安装这个包,但是你可以做的一般的事情是运行:core_properties.__dict__(注意双重_)它将告诉你你必须使用哪些属性。
  • @nbryans,我使用了以下代码 print(core_properties.__dict__)....但它只给了我 {'_element': ' at 0x10a64cdb8>}
  • 如果 core_properties are not enough,您希望删除哪些个人信息?
  • @Jezor, 说得更清楚一点,如果作者以外的人打开一个word文件并在上面写了一些cmets,我们需要删除评论它的人的名字,但我们仍然想要他制作的cmets。基本上我正在尝试设计一个盲目的同行评审流程
  • @Jezor,非常感谢,我已将问题编辑得更具体

标签: python python-docx


【解决方案1】:

CoreProperties类识别的核心属性在官方文档中列出:http://python-docx.readthedocs.io/en/latest/api/document.html#coreproperties-objects

要覆盖所有这些,您可以将它们设置为一个空字符串,就像您用来覆盖作者元数据的字符串一样:

document = Document('sampleFile.docx')
core_properties = document.core_properties
meta_fields= ["author", "category", "comments", "content_status", "created", "identifier", "keywords", "language", "revision", "subject", "title", "version"]
for meta_field in meta_fields:
    setattr(core_properties, meta_field, "")
document.save('new-filename.docx')

【讨论】:

  • core_properties 中的所有属性在我想做的事情中都没有用。文档是否还有其他属性可以帮助删除个人信息
  • 或者,您可以使用meta_fields = [attr for attr in dir(core_properties) if isinstance(getattr(core_properties, attr), str) and not attr.startswith("_")] 从文档中提取属性,而不是手动创建列表(它会查找这些文档的公共字符串属性)。
  • 说得更清楚一点,如果作者以外的人打开一个word文件并在上面写了一些cmets,我们需要删除评论它的人的名字,但我们仍然希望cmets他做了。基本上我正在尝试设计一个盲目的同行评审流程。
【解决方案2】:

如果您想从 .docx 文件中的 cmets 中删除个人信息,则必须深入研究文件本身。

所以,.docx 只是一个带有特定单词文件的 .zip 存档。我们需要覆盖它的一些内部文件,我能找到的最简单的方法是将所有文件复制到内存中,更改我们必须更改的所有内容并将其全部放入一个新文件中。

import re
import os
from zipfile import ZipFile

docx_file_name = '/path/to/your/document.docx'

files = dict()

# We read all of the files and store them in "files" dictionary.
document_as_zip = ZipFile(docx_file_name, 'r')
for internal_file in document_as_zip.infolist():
    file_reader = document_as_zip.open(internal_file.filename, "r")
    files[internal_file.filename] = file_reader.readlines()
    file_reader.close()

# We don't need to read anything more, so we close the file.
document_as_zip.close()

# If there are any comments.
if "word/comments.xml" in files.keys():
    # We will be working on comments file...
    comments = files["word/comments.xml"]

    comments_new = str()

    # Files contents have been read as list of byte strings.
    for comment in comments:
        if isinstance(comment, bytes):
            # Change every author to "Unknown Author".
            comments_new += re.sub(r'w:author="[^"]*"', "w:author=\"Unknown Author\"", comment.decode())

    files["word/comments.xml"] = comments_new

# Remove the old .docx file.
os.remove(docx_file_name)

# Now we want to save old files to the new archive.
document_as_zip = ZipFile(docx_file_name, 'w')
for internal_file_name in files.keys():
    # Those are lists of byte strings, so we merge them...
    merged_binary_data = str()
    for binary_data in files[internal_file_name]:
        # If the file was not edited (therefore is not the comments.xml file).
        if not isinstance(binary_data, str):
            binary_data = binary_data.decode()

        # Merge file contents.
        merged_binary_data += binary_data

    # We write old file contents to new file in new .docx.
    document_as_zip.writestr(internal_file_name, merged_binary_data)

# Close file for writing.
document_as_zip.close()

【讨论】:

  • 你能告诉我你在哪里找到了 updateable_zipfile 包吗?因为我搜索了它,我唯一得到的是 zipFile 包而不是 updateable_zipfile 包。关于如何获得它的任何建议......非常感谢
  • 好的,所以基本上updateable_zipfile是一个继承自zipfile包的类。
  • 你能告诉我如何安装 zipfile 包
  • 它也损坏了文件,恢复文件后评论的人的名字仍然存在
  • 非常感谢,我尝试在 libre 中打开该文档,它就像魅力一样。但它不适用于 Microsoft office word
猜你喜欢
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多