html清理脚本

html清理脚本

"""
html页面处理
html页面无法复制
保存页面后清理掉所有js代码。

正则过滤规则
自动跳转


删除css


删除分枝中的样式
style=".*?"

删除样式

"""

import os
import pathlib
import re
import chardet
import logging
from logging.config import dictConfig


def make_log_file_name():
    return pathlib.Path(__file__).stem + '.log'


class LevelFormatter(logging.Formatter):
    """自定义formatter实现不同级别日志不同格式输出
    """

    def __init__(self, fmt=None, datefmt=None, *args):
        self._default_formatters = logging.Formatter(
            '[%(asctime)s][%(lineno)d][%(levelname)s] - %(message)s', '%Y-%m-%d %H:%M:%S')
        self._level_formatters = {
            logging.INFO: logging.Formatter(r'%(message)s')}
        # self._fmt will be the default format
        super(LevelFormatter, self).__init__(fmt=fmt, datefmt=datefmt)

    def format(self, record):
        if record.levelno in self._level_formatters:
            return self._level_formatters[record.levelno].format(record)
        return self._default_formatters.format(record)
        # return super(LevelFormatter, self).format(record)


class FileProcessing(object):
    """
    文档处理基类
    """

    def __init__(self, work_path=None, **kwargs):
        """
        :work_path:工作目录
        """
        if work_path:
            self.work_path = pathlib.Path(work_path).absolute()
            if not self.work_path.exists():
                raise FileNotFoundError(work_path)
        else:
            self.work_path = pathlib.Path(__file__).parent.absolute()

        if str(self.work_path.absolute()).startswith('c:'):
            raise ValueError(f'禁止修改系统盘文件,请确认路径合法:{work_path}')

        self.file_filter = "*"
        self.root_path = pathlib.Path(__file__).parent
        self.log_path = self.root_path
        self.log_file = kwargs.get(
            'log_file', pathlib.Path(__file__).with_suffix('.log'))
        self.logger_config()

    def logger_config(self):

        # 日志配置
        # 日志器
        # - main 记录主程序日志,指向两个handler: main(error), info(info)

        LOG_CONF = {
            'version': 1,     # 版本号,目前只能为1,主要是为了以后配置升级提供兼容性
            # 声明日志格式化器
            'formatters': {
                'simple': {
                    # 格式化输出格式
                    'format': '[%(asctime)s][%(filename)s:%(lineno)d][%(levelname)s][%(process)d] - %(message)s',
                    'datefmt': '%Y-%m-%d %H:%M:%S'  # 日期的输出格式,即上面的asctime格式化参数
                },
                'simple2': {
                    'format': '%(message)s',
                    # 'class': '__main__.LevelFormatter'
                }

            },
            # 日志输出处理器,每一个键值对就是一个输出处理类
            'handlers': {
                'handler_file': {
                    'class': 'logging.FileHandler',  # 日志处理类
                    'mode': 'a',
                    'encoding': 'utf-8',
                    # 日志文件
                    'filename': self.log_path.joinpath(self.log_file),
                    'formatter': 'simple2',  # 日志格式类,前文声明
                    'level': 'INFO'  # 处理器等级
                },
                'handler_stream': {
                    'class': 'logging.StreamHandler',  # 日志处理类
                    'formatter': 'simple2',  # 日志格式类,前文声明
                    'level': 'INFO'  # 处理器等级
                },
            },

            # logger声明
            'loggers': {
                'main': {
                    'handlers': ['handler_file'],  # 处理器
                    'level': 'INFO',  # 日志等级,
                    'propagate': False,
                },
                'main.stream': {
                    'handlers': ['handler_stream'],  # 处理器
                    'level': 'INFO',  # 日志等级,
                    'propagate': True,
                },
            }
        }
        self.logger_main = logging.getLogger('main')
        # 子logger,传播至logger_main
        self.logger_stream = logging.getLogger('main.stream')
        self.logger_stream.propagate = False
        dictConfig(LOG_CONF)

        self.file_filter = "*"
        self.log_path = pathlib.Path(__file__).parent.absolute()
        self.log_file = make_log_file_name()
        self.logger_config()

    def logger_config(self):

        # 日志配置
        # 日志器
        # - main 记录主程序日志,指向两个handler: main(error), info(info)

        LOG_CONF = {
            'version': 1,     # 版本号,目前只能为1,主要是为了以后配置升级提供兼容性
            # 声明日志格式化器
            'formatters': {
                'simple': {
                    # 格式化输出格式
                    'format': '[%(asctime)s][%(filename)s:%(lineno)d][%(levelname)s][%(process)d] - %(message)s',
                    'datefmt': '%Y-%m-%d %H:%M:%S'  # 日期的输出格式,即上面的asctime格式化参数
                },
                'simple2': {
                    'format': '%(message)s'
                }

            },
            # 日志输出处理器,每一个键值对就是一个输出处理类
            'handlers': {
                'streamhandler': {
                    'class': 'logging.StreamHandler',  # 日志处理类
                    'formatter': 'simple2',  # 日志格式类,前文声明
                    'level': 'INFO'  # 处理器等级
                },
            },

            # logger声明
            'loggers': {
                'main': {
                    # 'handlers': ['handler_error', 'streamhandler'],  # 处理器
                    'handlers': ['streamhandler'],  # 处理器
                    'level': 'INFO',  # 日志等级,
                    'propagate': False,
                },
            }
        }
        self.logger = logging.getLogger('main')
        dictConfig(LOG_CONF)

    def get_file_list(self, path=None):
        """
        从指定目录根据文件名匹配式获取文件列表
        """
        if not (path.exists() and path.is_dir()):
            raise FileNotFoundError(path)
        file_list = [x for x in path.glob(
            self.file_filter) if x.is_file()]
        return file_list

    def start(self):
        raise NotImplementedError()


class HtmlConvert(FileProcessing):
    def __init__(self, work_path=None, filter_rule=None, file=None):
        super(HtmlConvert, self).__init__(work_path)
        if isinstance(file, (str, pathlib.Path)) and pathlib.Path(file).exists():
            self.file = file
        self.filter_rule = filter_rule or tuple()
        self.ex_charset = ['ansi', 'utf-8']
        self.file_filter = '*.html'
        self.errors = []

    def getfilecharset(self, fi):
        """
        获取文件的charset
        """
        with open(fi, 'rb') as fi:
            # u = chardet.UniversalDetector()
            return chardet.detect(fi.read())['encoding']

    def html_convert(self):
        """
        根据规则过滤html文本
        """
        if len(self.filter_rule) == 0:
            ValueError('过滤器必须非空。')
        file_list = self.get_file_list(self.work_path)
        file_list = list(filter(lambda x:not x.stem.endswith('_e'),file_list))
        

        self.logger.info(f'# 任务列表: {file_list}')
        for file in file_list:
            for c in (self.getfilecharset(file), *self.ex_charset):
                try:
                    fi = open(file, 'r+', encoding=c)
                    content = fi.read()
                    for r in self.filter_rule:
                        content = re.sub(*r, content)
                        # res = re.findall(r[0], content)
                        # self.logger.info(r[0])
                        # self.logger.info(res)
                        # a = input('input')

                    # res = re.findall(rule[0], content)
                    fi.seek(0)
                    fi.truncate(0)
                    fi.write(content)
                    self.logger.info(f'处理[{file}]成功。')
                    self.errors.clear()
                    break
                except UnicodeDecodeError as e:
                    self.errors.append((f'解析失败:[{file}][{c}]', e))
                finally:
                    fi.close()
        for x in self.errors:
            self.logger.error(x[0], exc_info=x[1])
        # self.logger.critical(f'处理{self.file}失败。')


def module_test():
    h = HtmlConvert(WORK_PATH, FILTER_RULE)
    h.html_convert()


    exit(0)


if __name__ == "__main__":

    FILTER_RULE = (
        (r']*?onerror[\s\S]*?>', ''),
        (r'', ''),
        (r'', ''),
        (r'style="[\s\S]*?"', ''),
        (r'', ''),
    (r'\n\s*\n', '\n'),
)

# WORK_PATH = r'C:\Users\dsnl\Desktop'
WORK_PATH = r''
if WORK_PATH == '':
    raise ValueError('WORK_PATH不能为空。')

# 测试
# module_test()

# 正式运行
obj = HtmlConvert(WORK_PATH, filter_rule=FILTER_RULE)
obj.html_convert()

bat脚本

python .\html_convert.py
echo off
echo %ERRORLEVEL%
if %ERRORLEVEL%==0 (
    echo "execute sucess."
) else (
    echo "execute cmd fail,please handle the error."
    pause   
)

posted @ 2025-10-12 18:11  木林森__𣛧  阅读(2)  评论(0)    收藏  举报