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()

增强功能说明:

  1. 多源输入支持

    • 本地HTML文件(自动检测)
    • 网页URL(自动下载)
    • HTML字符串(直接输入)
    • 标准输入(通过管道或重定向)
  2. 更多转换选项

    • --no-escape:禁用特殊字符转义
    • --no-wrap-lists:禁用列表项包裹
    • --skip-internal-links:跳过内部锚点链接
    • --reference-links:使用引用样式链接
    • --user-agent:自定义User-Agent
  3. 灵活的输入输出

    • 自动识别输入类型
    • 支持输出到文件或控制台
    • 支持管道操作

安装依赖:

pip install html2text requests

使用示例:

  1. 转换本地HTML文件
python html2md.py index.html -o output.md
  1. 转换网页URL
python html2md.py https://example.com -o example.md
  1. 直接转换HTML字符串
python html2md.py "<h1>标题</h1><p>段落内容</p>" --ignore-links
  1. 使用管道输入
curl -s https://example.com | python html2md.py --stdin -o example.md
  1. 复杂选项组合
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"
  1. 从文件读取并输出到控制台
python html2md.py input.html

高级功能说明:

  1. 智能URL处理

    • 自动检测有效的URL格式
    • 支持自定义User-Agent绕过反爬机制
    • 自动处理HTTP错误
  2. 管道集成

    • 可以从任何命令行工具接收HTML输入
    wget -qO- https://example.com | python html2md.py --stdin
    
  3. 特殊字符处理

    • 默认转义Markdown特殊字符(可通过--no-escape禁用)
    • 正确处理编码和特殊符号
  4. 链接处理选项

    • 引用样式链接([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)

注意事项:

  1. 对于复杂的JavaScript渲染页面,可能需要使用Selenium等工具先获取渲染后的HTML
  2. 转换结果可能因网站结构而异,对于复杂布局可能需要手动调整
  3. 使用--user-agent可以模拟浏览器访问,避免被网站拒绝
  4. 大文件转换可能需要调整系统编码或内存设置

此脚本提供了灵活的方式来处理各种HTML到Markdown的转换需求,适合批量处理本地文件、抓取网页内容或集成到自动化工作流中。