情境:工作需要為維持靜態網頁程式版面,預先以WORD編輯好版面,但另存成HMTL檔案,再貼到網站原始碼處。
但微軟WORD檔,另存成HTML時,常會殘留非必要之多餘資訊(如:CLASS、Meta),可經由PYTHON程式,將它部分簡潔化處理。
💙使用步驟一:將WORD文件,預先簡單排版,並另存新檔,下拉存檔類型(T): 已篩選的網頁(*.htm;*.html)
💙步驟二:將下面PYTHON程式,另存成Doc_2_HTML.py (前提:已預先安裝好PYTHON執行環境)
💙步驟三:將步驟一之HTML檔案,Drag-and-drop拖曳至Doc_2_HTML.py ,即可完成轉換產出處理。
PROMPT提示詞,產製PYTHON操作,如下:
你現在是資深網頁排版人員及PYTHON資深工程師,目前有一個微軟DOC檔,另存成HTML格式,
因為網頁程式無需WORD提供多餘內容(如:註解、Class屬性、span標籤等),請協助予以簡潔化處理後,產製PYTHON程式,
來源讀取以ARGC、ARGV方式進行,輸出檔名以輸入來源加入_OUT,如遇重覆再加入流水號。
💜可將此PYTHON程式,上傳給AI神器,並告訴AI程式您的新需求 (如:可將 font-family:標楷體 透過DIV之標籤,置於上方外框架處,並請重新產製完整PYTHON程式,將版面更精簡,如:wrap_with_div(soup)程式區塊),請它再重新產製完整PYTHON程式即可
💜PROMPT提示詞追補(請AI神器將本PYTHON程式,以Class類別方式改寫,並提供完整PYTHON程式及類別之方法詳細解說)。
import re
import os
import sys
import time
import chardet
from bs4 import BeautifulSoup, Comment ,Tag
import logging
import argparse
def detect_encoding(file_path):
"""
使用 chardet 庫檢測文件編碼
"""
with open(file_path, 'rb') as f:
raw_data = f.read()
result = chardet.detect(raw_data)
return result['encoding']
def remove_comments(soup):
"""
移除所有註解
"""
for comment in soup.find_all(string=lambda text: isinstance(text, Comment)):
comment.extract()
def remove_classes(soup):
"""
移除所有 class 屬性
"""
for tag in soup.find_all(class_=True):
del tag['class']
def remove_word_meta_tags(soup):
"""
移除 meta 標籤中生成器訊息
"""
for meta_tag in soup.find_all('meta', {'name': 'Generator', 'content': re.compile(r'Microsoft Word')}):
meta_tag.extract()
def remove_spans(soup):
"""
移除所有 span 標籤
"""
for span_tag in soup.find_all('span'):
span_tag.unwrap()
def unwrap_anchor_tags(soup):
"""
移除所有非 href 錨點標籤,但保留其中的内容
"""
for a_tag in soup.find_all('a', href=False):
a_tag.unwrap()
def remove_styles(soup):
"""
移除所有 style 屬性
"""
for tag in soup.find_all(style=True):
del tag['style']
def clean_style_tags(soup):
"""
移除所有含有 @font-face 和 @page 的註解,以及 Word 残留样式定义
"""
for style_tag in soup.find_all('style'):
if style_tag.string:
style_content = style_tag.string
style_content = re.sub(r'@font-face\s*\{[^}]*\}', '', style_content, flags=re.DOTALL)
style_content = re.sub(r'@page\s*[^}]*\}', '', style_content, flags=re.DOTALL)
style_content = re.sub(r'\/\*[^*]*\*+([^/*][^*]*\*+)*\/', '', style_content, flags=re.DOTALL)
style_content = re.sub(r'<!--[^>]*-->', '', style_content, flags=re.DOTALL)
style_content = re.sub(r'\s*\{[^}]*\}', '', style_content, flags=re.DOTALL) # Remove all remaining style definitions
if not style_content.strip():
style_tag.extract()
else:
style_tag.string.replace_with(style_content)
def remove_empty_paragraphs(soup):
"""
移除所有空的 p 標籤,只有內容为空或只包含空格的情况才移除
"""
for p_tag in soup.find_all('p'):
if not p_tag.text.strip():
p_tag.extract()
def process_tables(soup):
"""
處理表格,生成 summary 屬性並設置 scope 屬性
"""
for table in soup.find_all('table'):
# 檢查表格是否有標題列 (<th>)
has_header_row = any(tr.find('th') for tr in table.find_all('tr'))
if has_header_row:
# 如果有標題列,則使用標題列內容作為列名
headers = table.find_all('th')
column_names = [header.get_text(strip=True) for header in headers]
else:
# 如果沒有標題列,則使用第一列數據作為列名
first_row = table.find('tr')
if first_row:
column_names = [cell.get_text(strip=True) for cell in first_row.find_all(['th', 'td'])]
else:
# 如果表格為空,則設置列名為空列表
column_names = []
# 嘗試從前面的段落中獲取表格用途,並檢查其中是否包含 <b> 標籤
previous_element = table.find_previous('p')
if previous_element and previous_element.find('b'):
table_purpose = previous_element.b.get_text(strip=True) # 直接從 <b> 中提取文字
else:
# 如果沒有找到前面的段落或標題,使用表格的所有列名作為 table_purpose
table_purpose = "、".join(column_names) if column_names else "未知表格用途"
# 確保 column_names 包含有效的名稱,否則設置為 "未知"
column_names = [name if name else "未知" for name in column_names]
# 生成 summary 屬性文字,確保列數訊息正確
num_columns = len(column_names)
column_info = "、".join([f"第{i+1}直欄為{column_names[i]}" for i in range(num_columns)]) if num_columns > 0 else "無直欄位"
summary_text = f"{table_purpose},{column_info}。"
# 更新表格的 summary 屬性
table['summary'] = summary_text
# 設置 th 和 td 的 scope 屬性 (僅在有標題列時)
if has_header_row:
for th in headers:
th['scope'] = 'col'
for tr in table.find_all('tr'):
if tr.find('th'):
continue # 跳過表格標題行
for td in tr.find_all('td'):
td['scope'] = 'row'
# Debugging output to check the generated summary text
print("Generated summary text:", summary_text)
def wrap_with_div(soup):
"""用 <div> 標籤包裹整個文檔内容,並設置標楷體字體樣式"""
# 如果没有 html 標籤,則創建
if not soup.html:
new_html = soup.new_tag('html')
soup.append(new_html)
# 如果没有 body 標籤,則創建
if not soup.body:
soup.html.append(soup.new_tag('body'))
# 創建外部 div
outer_div = soup.new_tag("div", style="font-size:100%;font-family:'標楷體';")
# 將body 中的所有内容移動到外部 div
for child in soup.body.contents:
if isinstance(child, Tag):
outer_div.append(child.extract())
# 創建内部 div
inner_div = soup.new_tag("div")
inner_div.append(outer_div)
# 將内部 div 添加到 body
soup.body.append(inner_div)
def optimize_html_content(html_content, input_file):
"""
最佳化 HTML 內容,移除多餘資訊,並以輸入檔名加上 "_out" 命名輸出。
"""
try:
soup = BeautifulSoup(html_content, 'html.parser')
remove_comments(soup)
remove_classes(soup)
remove_word_meta_tags(soup)
remove_spans(soup)
unwrap_anchor_tags(soup)
remove_styles(soup)
clean_style_tags(soup)
remove_empty_paragraphs(soup)
process_tables(soup)
wrap_with_div(soup)
# 以輸入檔名加上 "_out" 命名輸出檔案,處理重複情況(加入流水號)
base_filename, ext = os.path.splitext(input_file)
filename = f"{base_filename}_out{ext}"
counter = 1
while os.path.exists(filename):
filename = f"{base_filename}_out_{counter}{ext}"
counter += 1
# 寫入修改後的 HTML 內容,使用 'utf-8' 編碼
with open(filename, 'w', encoding='utf-8') as file:
file.write(str(soup))
# 列印儲存的檔案名稱
print(f"已儲存最佳化後的 HTML 檔案:{filename}")
except Exception as e:
# 列印錯誤訊息
logging.error(f"發生錯誤:{e}", exc_info=True)
# 等待5秒鐘以便使用者查看錯誤訊息
time.sleep(5)
def main():
parser = argparse.ArgumentParser(description='優化HTML文件内容')
parser.add_argument('filename', help='輸入的HTML文件名')
args = parser.parse_args()
input_file = args.filename
try:
# 使用 chardet 庫檢測文件編碼
detected_encoding = detect_encoding(input_file)
# 使用正確的編碼讀取文件
with open(input_file, 'r', encoding=detected_encoding) as file:
html_content = file.read()
optimize_html_content(html_content, input_file)
except FileNotFoundError:
logging.error(f"找不到檔案: {input_file}")
time.sleep(5)
except Exception as e:
logging.error(f"發生錯誤:{e}", exc_info=True)
time.sleep(5)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()
相關查詢:
Removes unnecessary HTML tags from Word documents and outputs clean HTML.
Word文書から生成されるHTMLの不要な情報を取り除いて、きれいなHTMLを出力します。