8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

提取 DOCX 注释

Louise Sørensen 1月前

62 0

我是一名教师。我想要一份对我布置的论文发表评论的所有学​​生的名单,以及他们说了什么。Drive API 对我来说太难了,但我想我可以将它们下载为......

我是一名教师。我想要一份对我布置的论文发表评论的所有学​​生的名单,以及他们说了什么。Drive API 对我来说太难了,但我想我可以将它们下载为 zip 文件并解析 XML。

评论用标签 w:comment 标记,其中 w:t 表示评论文本, 表示评论内容。这应该很容易,但是 XML (etree) 让我很头疼。

通过教程(和官方 Python 文档):

z = zipfile.ZipFile('test.docx')
x = z.read('word/comments.xml')
tree = etree.XML(x)

然后我这样做:

children = tree.getiterator()
for c in children:
    print(c.attrib)

结果是:

{}
{'{http://schemas.openxmlformats.org/wordprocessingml/2006/main}author': 'Joe Shmoe', '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}id': '1', '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}date': '2017-11-17T16:58:27Z'}
{'{http://schemas.openxmlformats.org/wordprocessingml/2006/main}rsidR': '00000000', '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}rsidDel': '00000000', '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}rsidP': '00000000', '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}rsidRDefault': '00000000', '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}rsidRPr': '00000000'}
{}
{'{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val': '0'}
{'{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val': '0'}
{'{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val': '0'}

此后,我完全陷入了困境。我试过了 element.get() ,但 element.findall() 没成功。即使我复制/粘贴值 ( '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val' ),我也会得到 None 回报。

有人可以帮忙吗?

帖子版权声明 1、本帖标题:提取 DOCX 注释
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Louise Sørensen在本站《parsing》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 您的答案可以通过添加额外的支持信息来改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心找到有关如何撰写良好答案的更多信息。

  • 如果您还想要与评论相关的文本:

    def get_document_comments(docxFileName):
           comments_dict = {}
           comments_of_dict = {}
           docx_zip = zipfile.ZipFile(docxFileName)
           comments_xml = docx_zip.read('word/comments.xml')
           comments_of_xml = docx_zip.read('word/document.xml')
           et_comments = etree.XML(comments_xml)
           et_comments_of = etree.XML(comments_of_xml)
           comments = et_comments.xpath('//w:comment', namespaces=ooXMLns)
           comments_of = et_comments_of.xpath('//w:commentRangeStart', namespaces=ooXMLns)
           for c in comments:
              comment = c.xpath('string(.)', namespaces=ooXMLns)
              comment_id = c.xpath('@w:id', namespaces=ooXMLns)[0]
              comments_dict[comment_id] = comment
           for c in comments_of:
              comments_of_id = c.xpath('@w:id', namespaces=ooXMLns)[0]
              parts = et_comments_of.xpath(
                "//w:r[preceding-sibling::w:commentRangeStart[@w:id=" + comments_of_id + "] and following-sibling::w:commentRangeEnd[@w:id=" + comments_of_id + "]]",
                namespaces=ooXMLns)
              comment_of = ''
              for part in parts:
                 comment_of += part.xpath('string(.)', namespaces=ooXMLns)
                 comments_of_dict[comments_of_id] = comment_of
            return comments_dict, comments_of_dict
    
  • @lucid_dreamer:Word Automation 需要 Microsoft Word,在服务器部署中不可靠。如果您需要在纯 Python 解决方案中引用文本,而不需要 Word,请提出新问题。

  • tsul 1月前 0 只看Ta
    引用 5

    我使用 Word 对象模型 从 Word 文档中提取带有回复的评论。有关评论对象的文档可 在此处 。此文档使用 Visual Basic for Applications (VBA)。但我能够使用 Python 中的函数,只需稍加修改即可。Word 对象模型的唯一问题是我必须使用 pywin32 中的 win32com 包,它在 Windows PC 上运行良好,但我不确定它是否可以在 macOS 上运行。

    这是我用来提取带有相关回复的评论的示例代码:

        import win32com.client as win32
        from win32com.client import constants
    
        word = win32.gencache.EnsureDispatch('Word.Application')
        word.Visible = False 
        filepath = "path\to\file.docx"
    
        def get_comments(filepath):
            doc = word.Documents.Open(filepath) 
            doc.Activate()
            activeDoc = word.ActiveDocument
            for c in activeDoc.Comments: 
                if c.Ancestor is None: #checking if this is a top-level comment
                    print("Comment by: " + c.Author)
                    print("Comment text: " + c.Range.Text) #text of the comment
                    print("Regarding: " + c.Scope.Text) #text of the original document where the comment is anchored 
                    if len(c.Replies)> 0: #if the comment has replies
                        print("Number of replies: " + str(len(c.Replies)))
                        for r in range(1, len(c.Replies)+1):
                            print("Reply by: " + c.Replies(r).Author)
                            print("Reply text: " + c.Replies(r).Range.Text) #text of the reply
            doc.Close()
    
  • 感谢 @kjhughes 提供的出色答案,从文档文件中提取了所有评论。我和本主题中的其他人一样,也遇到了获取评论相关文本的问题。我以 @kjhughes 的代码为基础,尝试使用 python-docx 来解决这个问题。以下是我的看法。

    示例文件。

    我将提取该评论以及文档中引用该评论的段落。

    from docx import Document
    from lxml import etree
    import zipfile
    ooXMLns = {'w':'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
    #Function to extract all the comments of document(Same as accepted answer)
    #Returns a dictionary with comment id as key and comment string as value
    def get_document_comments(docxFileName):
        comments_dict={}
        docxZip = zipfile.ZipFile(docxFileName)
        commentsXML = docxZip.read('word/comments.xml')
        et = etree.XML(commentsXML)
        comments = et.xpath('//w:comment',namespaces=ooXMLns)
        for c in comments:
            comment=c.xpath('string(.)',namespaces=ooXMLns)
            comment_id=c.xpath('@w:id',namespaces=ooXMLns)[0]
            comments_dict[comment_id]=comment
        return comments_dict
    #Function to fetch all the comments in a paragraph
    def paragraph_comments(paragraph,comments_dict):
        comments=[]
        for run in paragraph.runs:
            comment_reference=run._r.xpath("./w:commentReference")
            if comment_reference:
                comment_id=comment_reference[0].xpath('@w:id',namespaces=ooXMLns)[0]
                comment=comments_dict[comment_id]
                comments.append(comment)
        return comments
    #Function to fetch all comments with their referenced paragraph
    #This will return list like this [{'Paragraph text': [comment 1,comment 2]}]
    def comments_with_reference_paragraph(docxFileName):
        document = Document(docxFileName)
        comments_dict=get_document_comments(docxFileName)
        comments_with_their_reference_paragraph=[]
        for paragraph in document.paragraphs:  
            if comments_dict: 
                comments=paragraph_comments(paragraph,comments_dict)  
                if comments:
                    comments_with_their_reference_paragraph.append({paragraph.text: comments})
        return comments_with_their_reference_paragraph
    if __name__=="__main__":
        document="test.docx"  #filepath for the input document
        print(comments_with_reference_paragraph(document))
    

    示例文档的输出如下所示

    我已经在段落级别完成了此操作。 这也可以在 python-docx 运行级别完成。 希望这会有所帮助。

  • 获取文本时,评论与以下内容相关:1) 公认的 xpath 解决方案的难点是读取 docxZip.read('word/document.xml'),然后解析它以通过评论的 id 找到评论锚点 (w:commentRangeStart)...一次性解决方案需要做这么多工作 :-) 2) 简单的方法是使用带有 win32 api 的示例,因为我们讨论的不是服务器部署,而是个人使用的本地桌面脚本,用于解析一些学校论文... 编码时间很重要。win32 示例就是这样做的。

  • 考虑到 OOXML 是一种如此复杂的格式,你已经取得了很大的进步。

    下面是一些示例 Python 代码,展示如何通过 XPath 访问 DOCX 文件的注释:

    from lxml import etree
    import zipfile
    
    ooXMLns = {'w':'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
    
    def get_comments(docxFileName):
      docxZip = zipfile.ZipFile(docxFileName)
      commentsXML = docxZip.read('word/comments.xml')
      et = etree.XML(commentsXML)
      comments = et.xpath('//w:comment',namespaces=ooXMLns)
      for c in comments:
        # attributes:
        print(c.xpath('@w:author',namespaces=ooXMLns))
        print(c.xpath('@w:date',namespaces=ooXMLns))
        # string value of the comment:
        print(c.xpath('string(.)',namespaces=ooXMLns))
    
返回
作者最近主题: