Python:讀取 .doc、.docx 兩種 Word 文件簡述及“Word 未能引發事件”錯誤

来源:https://www.cnblogs.com/gl1573/archive/2018/12/14/10114839.html
-Advertisement-
Play Games

Python 中可以讀取 word 文件的庫有 python-docx 和 pywin32。 pywin32 這個庫很強大,不僅僅可以讀取 word,但是網上介紹用 pywin32 讀取 .doc 的文章真不多,因為,真心不好用。 以下是 pywin32 讀取 .doc 的代碼示例,但是讀取表格有問 ...


Python 中可以讀取 word 文件的庫有 python-docx 和 pywin32。

  優點 缺點
python-docx 跨平臺 只能處理 .docx 格式,不能處理.doc格式
pywin32 僅限 windows 平臺 .doc 和 .docx 都能處理

pywin32

這個庫很強大,不僅僅可以讀取 word,但是網上介紹用 pywin32 讀取 .doc 的文章真不多,因為,真心不好用。

以下是 pywin32 讀取 .doc 的代碼示例,但是讀取表格有問題,輸出全是空,原因不明,因為不打算用所以沒有深入研究。另外,如果表格中有縱向合併單元格,會報錯:“無法訪問此集合中單獨的行,因為表格有縱向合併的單元格。”

from win32com.client import Dispatch

word = Dispatch('Word.Application')     # 打開word應用程式
# word = DispatchEx('Word.Application') # 啟動獨立的進程
word.Visible = 0        # 後臺運行,不顯示
word.DisplayAlerts = 0  # 不警告

path = r'E:\abc\test.doc'
doc = word.Documents.Open(FileName=path, Encoding='gbk')

for para in doc.paragraphs:
    print(para.Range.Text)

for t in doc.Tables:
    for row in t.Rows:
        for cell in row.Cells:
            print(cell.Range.Text)

doc.Close()
word.Quit

但是 pywin32 有另外一個功能,就是將 .doc 格式另存為 .docx 格式,這樣我們就可以使用 python-docx 來處理了。

def doc2docx(path):
    w = win32com.client.Dispatch('Word.Application')
    w.Visible = 0
    w.DisplayAlerts = 0
    doc = w.Documents.Open(path)
    newpath = os.path.splitext(path)[0] + '.docx'
    doc.SaveAs(newpath, 12, False, "", True, "", False, False, False, False)
    doc.Close()
    w.Quit()
    os.remove(path)
    return newpath

 

python-docx

import docx

fn = r'E:\abc\test.docx'
doc = docx.Document(fn)

for paragraph in doc.paragraphs:
        print(paragraph.text)

for table in doc.tables:
    for row in table.rows:
        for cell in row.cells:
            print(cell.text)

對於縱向合併單元格,python-docx 的處理也很貼心。

 

Word 未能引發事件

我的爬蟲在爬取到 .doc 文件之後,就通過上面的方法將其轉為 .docx 格式,原本一切都好,下班掛機在跑,第二天來一看,報了這個錯:

我用報錯的文件單獨調試了 doc2docx 方法,並沒有報錯。網上查了這個錯誤,沒有啥收穫。

反覆測試後發現總是那個網頁報錯,說明 bug 可以重現,問題是到底是哪裡報錯。

我將代碼一行行刪去,直到只留下執行到報錯所必須的代碼:

def get_winningbid_detail(url, name):
    r = requests.get(url)
    r.encoding = 'utf-8'
    html = r.text
    soup = BeautifulSoup(html, 'lxml')

    ps = soup.find_all(text=re.compile('附件'))
    if len(ps) > 0:
        os.makedirs(os.path.join(download_dir, name), exist_ok=True)
        for p in ps:
            a_tab = p.find_next_sibling('a')
            if a_tab is not None:
                link = homepage + a_tab['href']
                localfilename = os.path.join(download_dir, name, a_tab.text)
                # print(localfilename)
                with open(localfilename, 'wb+') as sw:
                    sw.write(requests.get(link).content)
                if localfilename.endswith('.doc'):
                    doc2docx(localfilename)

反覆讀這段代碼,並沒有發現什麼問題。

因為有些網頁的附件名稱是相同的,例如 公告.doc,所以我按每個網頁的標題(在總覽頁面爬到的)分文件夾放置下載的文件,所以方法中傳了一個 name 參數,而如果 name 參數傳空,則不會報錯。

其實由此已經可以發現 bug 所在了,但我卻沒想到,又反覆折騰了很久才發現,原來是文件名太長了。

在windows下麵,單個文件名的長度限制是255,完整的路徑長度(如 E:\abc\test.doc)這樣限制是260,一個漢字占2個字元。

路徑最後有一個字元串結束符 '\0' 要占掉一個字元,所以完整路徑實際限長是259。

 


 

相關博文推薦:

Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及對比

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前採用 和`python`兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 :) 原文地址是: "《每天一個設計模式之命令模式》" 歡迎關註個人技術博客: "godbmw.com" 。每周 1 篇原創技術分 ...
  • 迭代器模式,Iterator,java集合框架內置的一種模式,本文介紹了迭代器模式的起源含義,設計意圖,以及結構形態,並且給出了Java版本的迭代器模式的實現,迭代器模式分為內部迭代和外部迭代,Java集合框架使用的這種形式是比較好的一種方式。 ...
  • 一. Python程式中, 文件的處理步驟是什麼? 二. 文本打開時設置的模式有哪些? 分別代表什麼意思? 三. os模塊中提供的常用文件操作? 四. 代碼實現: 大文件拷貝操作 註意: 不能一次性讀取大文件內容, 容易造成記憶體峰值 五. 代碼實現: 假設一個文件夾中有很多不同格式的文件, 要求: ...
  • 126.Struts2中的攔截器有什麼用?列舉框架提供的攔截器名稱? 127.Struts2有哪些優點? 128.ActionContext和ValueStack什麼時候創建?是否是線程安全的? 129.一個請求在Struts2框架中的處理大概分為幾個步驟? 130.介紹一下Struts的Actio ...
  • activemq配置jmx 配置activemq中的jmx可以用於監控activemq信息。 activemq.xml配置 修改broker屬性 添加節點managementContext <managementContext> <managementContext createConnector= ...
  • 更新Composer依賴報錯處理 Fatal error: Declaration of Fxp\Composer\AssetPlugin\Repository\AbstractAssetsRe pository::search() must be compatible with Composer\... ...
  • 在 WEB 項目中返回 JSON 數據是常見的交互形式,在 Spring Boot 中這一切都變得十分簡單。So easy!!! 你所需具備的基礎 "什麼是 Spring Boot?" "Spring Boot 核心配置文件詳解" "Spring Boot 開啟的 2 種方式" "Spring Bo ...
  • 簡介 從今天開始,我們嘗試用2篇博客的內容量,搞定一個網站叫做“美空網”網址為:http://www.moko.cc/, 這個網站我分析了一下,我們要爬取的圖片在 下麵這個網址 http://www.moko.cc/post/1302075.html 然後在去分析一下,我需要找到一個圖片列表頁面是最 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...