HTML转Markdown脚本,支持多种输入来源(HTML字符串、本地HTML文件、URL)并提供更多转换选项:
import html2text
import argparse
import requests
from pathlib import Path
from urllib.parse import urlparse
import sys
def html_to_markdown(html_content, **options):
"""
将HTML内容转换为Markdown格式
参数:
html_content: str - 输入的HTML字符串
**options: 转换选项:
- ignore_links: bool (默认False) 是否忽略链接
- ignore_images: bool (默认False) 是否忽略图片
- body_width: int (默认0) 换行宽度(0=不换行)
- single_line_break: bool (默认False) 是否使用单换行符
- escape_special_chars: bool (默认True) 是否转义特殊字符
- wrap_list_items: bool (默认True) 包裹列表项
- skip_internal_links: bool (默认False) 跳过内部链接
- reference_links: bool (默认False) 使用引用样式链接
返回:
str: 转换后的Markdown内容
"""
# 创建转换器并配置选项
converter = html2text.HTML2Text()
# 设置转换选项
converter.ignore_links = options.get('ignore_links', False)
converter.ignore_images = options.get('ignore_images', False)
converter.body_width = options.get('body_width', 0)
converter.single_line_break = options.get('single_line_break', False)
converter.escape_special_chars = options.get('escape_special_chars', True)
converter.wrap_list_items = options.get('wrap_list_items', True)
converter.skip_internal_links = options.get('skip_internal_links', False)
converter.reference_links = options.get('reference_links', False)
# 执行转换
return converter.handle(html_content)
def get_html_from_source(source, **kwargs):
"""
从不同来源获取HTML内容
参数:
source: str - 输入源(文件路径、URL或HTML字符串)
返回:
str: HTML内容
"""
# 检查是否是文件路径
if Path(source).exists():
with open(source, 'r', encoding='utf-8') as f:
return f.read()
# 检查是否是URL
parsed = urlparse(source)
if parsed.scheme and parsed.netloc:
user_agent = kwargs.get('user_agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36')
headers = {'User-Agent': user_agent}
response = requests.get(source, headers=headers)
response.raise_for_status()
return response.text
# 否则视为HTML字符串
return source
def convert_html(source, output=None, **options):
"""
转换HTML为Markdown
参数:
source: str - 输入源(文件路径、URL或HTML字符串)
output: str - 输出文件路径(可选)
**options: 转换选项
"""
# 获取HTML内容
try:
html_content = get_html_from_source(source, **options)
except Exception as e:
print(f"获取内容失败: {e}")
sys.exit(1)
# 转换内容
markdown_content = html_to_markdown(html_content, **options)
# 处理输出
if output:
# 输出到文件
with open(output, 'w', encoding='utf-8') as f:
f.write(markdown_content)
print(f"转换完成! 输出文件: {output}")
else:
# 输出到控制台
print(markdown_content)
def main():
parser = argparse.ArgumentParser(
description='HTML转Markdown转换工具 - 支持文件、URL和HTML字符串输入',
formatter_class=argparse.RawTextHelpFormatter
)
# 输入源参数
parser.add_argument('source', nargs='?', default=None,
help='输入源(文件路径、URL或HTML字符串)\n'
'示例:\n'
' 本地文件: index.html\n'
' URL: https://example.com\n'
' HTML字符串: "<h1>标题</h1>"')
# 输出选项
parser.add_argument('-o', '--output',
help='输出Markdown文件路径(可选)')
# 转换选项
parser.add_argument('--ignore-links', action='store_true',
help='忽略所有链接')
parser.add_argument('--ignore-images', action='store_true',
help='忽略所有图片')
parser.add_argument('--body-width', type=int, default=0,
help='设置换行宽度(0=禁用换行, 默认:0)')
parser.add_argument('--single-line-break', action='store_true',
help='使用单换行符代替双换行符')
parser.add_argument('--no-escape', action='store_false', dest='escape_special_chars',
help='禁用特殊字符转义')
parser.add_argument('--no-wrap-lists', action='store_false', dest='wrap_list_items',
help='禁用列表项包裹')
parser.add_argument('--skip-internal-links', action='store_true',
help='跳过内部链接(#anchor)')
parser.add_argument('--reference-links', action='store_true',
help='使用引用样式链接')
parser.add_argument('--user-agent', default='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
help='自定义User-Agent(用于URL请求)')
# 从标准输入读取HTML
parser.add_argument('--stdin', action='store_true',
help='从标准输入读取HTML内容')
args = parser.parse_args()
# 处理输入源
if args.stdin:
# 从标准输入读取
source = sys.stdin.read()
elif not args.source:
parser.print_help()
return
else:
source = args.source
# 执行转换
convert_html(
source=source,
output=args.output,
ignore_links=args.ignore_links,
ignore_images=args.ignore_images,
body_width=args.body_width,
single_line_break=args.single_line_break,
escape_special_chars=args.escape_special_chars,
wrap_list_items=args.wrap_list_items,
skip_internal_links=args.skip_internal_links,
reference_links=args.reference_links,
user_agent=args.user_agent
)
if __name__ == "__main__":
main()
增强功能说明:
多源输入支持:
- 本地HTML文件(自动检测)
- 网页URL(自动下载)
- HTML字符串(直接输入)
- 标准输入(通过管道或重定向)
更多转换选项:
--no-escape:禁用特殊字符转义--no-wrap-lists:禁用列表项包裹--skip-internal-links:跳过内部锚点链接--reference-links:使用引用样式链接--user-agent:自定义User-Agent
灵活的输入输出:
- 自动识别输入类型
- 支持输出到文件或控制台
- 支持管道操作
安装依赖:
pip install html2text requests
使用示例:
- 转换本地HTML文件:
python html2md.py index.html -o output.md
- 转换网页URL:
python html2md.py https://example.com -o example.md
- 直接转换HTML字符串:
python html2md.py "<h1>标题</h1><p>段落内容</p>" --ignore-links
- 使用管道输入:
curl -s https://example.com | python html2md.py --stdin -o example.md
- 复杂选项组合:
python html2md.py https://news.site/article.html \
-o article.md \
--ignore-images \
--body-width=80 \
--reference-links \
--user-agent="My-Custom-User-Agent/1.0"
- 从文件读取并输出到控制台:
python html2md.py input.html
高级功能说明:
智能URL处理:
- 自动检测有效的URL格式
- 支持自定义User-Agent绕过反爬机制
- 自动处理HTTP错误
管道集成:
- 可以从任何命令行工具接收HTML输入
wget -qO- https://example.com | python html2md.py --stdin特殊字符处理:
- 默认转义Markdown特殊字符(可通过
--no-escape禁用) - 正确处理编码和特殊符号
- 默认转义Markdown特殊字符(可通过
链接处理选项:
- 引用样式链接(
[text][id]+[id]: url) - 跳过内部页面锚点链接
- 完全忽略链接或图片
- 引用样式链接(
转换示例:
输入URL:
python html2md.py https://example.com
输出Markdown:
# Example Domain
This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.
[More information...](https://www.iana.org/domains/example)
注意事项:
- 对于复杂的JavaScript渲染页面,可能需要使用Selenium等工具先获取渲染后的HTML
- 转换结果可能因网站结构而异,对于复杂布局可能需要手动调整
- 使用
--user-agent可以模拟浏览器访问,避免被网站拒绝 - 大文件转换可能需要调整系统编码或内存设置
此脚本提供了灵活的方式来处理各种HTML到Markdown的转换需求,适合批量处理本地文件、抓取网页内容或集成到自动化工作流中。