Python epub電子書檔案解析_中文斷句處理_以國家科幻叢書十一_機器人風波(The Soul of the Robot)為例

 




此次實驗採用
好讀平台上面的
書名:機器人風波(The Soul of the Robot)
作者: 巴靈頓・貝雷(Barrington J.Bayley)
譯者:王凱竹
https://www.haodoo.net/?M=Share&P=1010490641#gsc.tab=0
作者簡介:
巴靈頓.貝雷
出生於英國伯明翰,一九六零年代科幻小說新浪潮運動在英國的推手之一。
寫作風格憂鬱、陰沉,影響後來多名英國科幻作家。


這個平台的定位有點類似台灣版本的日本青空文庫
青空文庫是蒐集了日本國內著作權已經進入公有領域的文學作品的數位圖書館。

程式碼範例ver1.
"""
【免責聲明 / Disclaimer】

1. 本程式僅供技術研究與學術交流使用,不保證程式碼完全無誤或適用於特定商業目的。
   This code is for technical research and academic exchange only.
   There is no guarantee of accuracy or fitness for any particular purpose.

2. 使用者應確保所處理之 EPUB 檔案具備合法授權。本程式作者不承擔因非法使用版權
   作品(如未經授權之重製、散佈或進行機器學習訓練)所產生之法律責任。
   Users are responsible for ensuring they have legal authorization for the EPUB files.
   The author assumes no liability for legal issues arising from unauthorized use
   of copyrighted works (e.g., reproduction, distribution, or ML training).

3. 請遵守相關著作權法規。針對已受版權保護之作品,建議僅在「合理使用」範圍內操作。
   Please comply with copyright laws. For protected works, operations should be
   limited to the scope of "Fair Use."
"""
import ebooklib
from ebooklib import epub
from bs4 import BeautifulSoup
import re


def epub_to_sentences(file_path):
    # 1. 讀取 EPUB
    book = epub.read_epub(file_path)
    raw_text = ""

    # 2. 提取所有文檔章節
    for item in book.get_items():
        if item.get_type() == ebooklib.ITEM_DOCUMENT:
            # 使用 BeautifulSoup 清除 HTML 標籤
            soup = BeautifulSoup(item.get_content(), 'html.parser')
            raw_text += soup.get_text() + "\n"

    # 3. 文本清理 (去除多餘空白、換行)
    cleaned_text = re.sub(r'\s+', ' ', raw_text).strip()

    # 4. 斷句邏輯
    # 使用正則表達式,遇到句號、驚嘆號、問號就斷行
    # (?<=[。!?]) 表示匹配這些符號的後方位置
    sentences = re.split(r'(?<=[。!?])', cleaned_text)

    # 移除空字串並去除前後空白
    sentences = [s.strip() for s in sentences if s.strip()]

    return sentences


# 使用範例
file_name = r"E:\NLP\epub_dataset\The_Soul_of_the_Robot.epub"
all_sentences = epub_to_sentences(file_name)

# 儲存為訓練用的 txt 檔
with open("training_data.txt", "w", encoding="utf-8") as f:
    for line in all_sentences:
        f.write(line + "\n")

print(f"處理完成!共提取 {len(all_sentences)} 個句子。")

程式運行後會告知總計此本書共有幾個句子

滾到最後一頁比對是否真的擷取到文本尾端

這邊斷句方式可能在引號與標點的層次還有改善空間
原先上一個版本中文斷句處理,透過正規表達式濾除方法有些邏輯疏失。
當找到一個位置,它的左邊緊鄰著「。」、「!」或「?」,然後在這個位置切一刀。
之前作法過於武斷,只要看到標點就切,完全不考慮標點後面是否還有相關連的符號(例如引號)。

為了確保餵入後續AI模型訓練的每一句都要是一句完整語意單位,在此修改第二版斷句解析。
程式碼範例ver2.

"""
【免責聲明 / Disclaimer】

1. 本程式僅供技術研究與學術交流使用,不保證程式碼完全無誤或適用於特定商業目的。
   This code is for technical research and academic exchange only.
   There is no guarantee of accuracy or fitness for any particular purpose.

2. 使用者應確保所處理之 EPUB 檔案具備合法授權。本程式作者不承擔因非法使用版權
   作品(如未經授權之重製、散佈或進行機器學習訓練)所產生之法律責任。
   Users are responsible for ensuring they have legal authorization for the EPUB files.
   The author assumes no liability for legal issues arising from unauthorized use
   of copyrighted works (e.g., reproduction, distribution, or ML training).

3. 請遵守相關著作權法規。針對已受版權保護之作品,建議僅在「合理使用」範圍內操作。
   Please comply with copyright laws. For protected works, operations should be
   limited to the scope of "Fair Use."
"""
import ebooklib
from ebooklib import epub
from bs4 import BeautifulSoup
import re


def epub_to_sentences(file_path):
    # 1. 讀取 EPUB
    book = epub.read_epub(file_path)
    raw_text = ""

    # 2. 提取所有文檔章節
    for item in book.get_items():
        if item.get_type() == ebooklib.ITEM_DOCUMENT:
            # 使用 BeautifulSoup 清除 HTML 標籤
            soup = BeautifulSoup(item.get_content(), 'html.parser')
            raw_text += soup.get_text() + "\n"

    # 3. 文本清理 (去除多餘空白、換行)
    cleaned_text = raw_text.replace('\n', '').replace('\r', '')
    cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()

    # 4. 斷句邏輯:匹配「標點」且「後面不是引號」,或者「標點+引號」
    pattern = r'(?<=[。!?])(?![」』])|(?<=[。!?][」』])'
    sentences = re.split(pattern, cleaned_text)

    # 移除空字串並去除前後空白
    sentences = [s.strip() for s in sentences if s.strip()]

    return sentences


# 使用範例
file_name = r"E:\NLP\epub_dataset\The_Soul_of_the_Robot.epub"
all_sentences = epub_to_sentences(file_name)

# 儲存為訓練用的 txt 檔
with open("training_data.txt", "w", encoding="utf-8") as f:
    for line in all_sentences:
        f.write(line + "\n")

print(f"處理完成!共提取 {len(all_sentences)} 個句子。")

斷句效果就比較正確了




留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

外貿Payment Term 付款條件(方式)常見的英文縮寫與定義

鼎新ERP_會計系統_總帳管理_財務參數設定_傳票處理