Сжатие (минимизация) HTML из python

Как сжать(минимизировать) HTML из python; я знаю, что могу использовать некоторые регулярные выражения для удаления пробелов и других вещей, но я хочу, чтобы настоящий компилятор использовал чистый python (поэтому его можно использовать в Google App Engine).

Я сделал тест на онлайн-компрессоре html, и он сохранил 65% размера html. Я хочу этого, но от python.

4 ответов


вы можете использовать htmlmin для минимизации html:

import htmlmin

html = """
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Case</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body> 
<div class="container">
  <h2>Well</h2>
  <div class="well">Basic Well</div>
</div>
</body>
</html>
"""

minified = htmlmin.minify(html.decode("utf-8"), remove_empty_space=True)
print(minified)

Я полагаю, что в GAE нет необходимости минимизировать ваш html, поскольку GAE уже gzip it кэширование & GZip на GAE (сообщество Wiki)

Я не тестировал, но уменьшенная версия html, вероятно, выиграет только 1% от размера, поскольку она удаляет только пространство после сжатия обеих версий.

Если вы хотите сохранить хранилище, например, memcached, у вас больше интереса к gzip (даже при низком уровне сжатия), чем к удалению пространства, как в python вероятно, меньше и быстрее, как обработано в C вместо чистого python


htmlmin и html_slimmer некоторые простые инструменты HTML minifying для python. У меня есть миллионы html-страниц, хранящихся в моей базе данных и работающих под управлением htmlmin, я могу уменьшить размер страницы между 5 и 50%. Ни один из них не выполняет оптимальную работу при полной минификации html (т. е. цвет шрифта #00000 можно уменьшить до #000), но это хорошее начало. У меня есть блок try / except, который запускает htmlmin, а затем, если это не удается, html_slimmer, потому что htmlmin, похоже, предоставляет лучшее сжатие, но оно не поддерживает символы, отличные от ascii.

Пример Кода:

import htmlmin
from slimmer import html_slimmer # or xhtml_slimmer, css_slimmer
try:
    html=htmlmin.minify(html, remove_comments=True, remove_empty_space=True)
except:
    html=html_slimmer( html.strip().replace('\n',' ').replace('\t',' ').replace('\r',' ')  )

Удачи!


Я написал сценарий сборки, который дублирует Мои шаблоны в другой каталог, а затем я использую этот трюк, чтобы сказать моему приложению выбрать правильный шаблон в режиме разработки или в производстве:

DEV = os.environ['SERVER_SOFTWARE'].startswith('Development') and not PRODUCTION_MODE

TEMPLATE_DIR = 'templates/2012/head/' if DEV else 'templates/2012/output/'

ли это gzipped вашим веб-сервером на самом деле не точка, вы должны сохранить каждый байт, который вы можете по соображениям производительности.

если вы посмотрите на некоторые из самых больших сайтов, они часто делают такие вещи, как написание недопустимого html для сохранения байтов, для например, в атрибутах id в тегах html обычно опускаются двойные кавычки, например:

<did id=mydiv> ... </div>

вместо:

<did id="mydiv"> ... </div>

и есть несколько примеров, но это не относится к области потока, я думаю.

вернемся к вопросу, я собрал небольшой скрипт сборки, который минимизирует ваш HTML, CSS и JS. Предостережение: оно не покрывает случай PRE бирки.

import os
import re
import sys

from subprocess import call

HEAD_DIR = 'templates/2012/head/'

OUT_DIR = 'templates/2012/output/'

REMOVE_WS = re.compile(r"\s{2,}").sub

YUI_COMPRESSOR = 'java -jar tools/yuicompressor-2.4.7.jar '

CLOSURE_COMPILER = 'java -jar tools/compiler.jar  --compilation_level ADVANCED_OPTIMIZATIONS '

def ensure_dir(f):
    d = os.path.dirname(f)
    if not os.path.exists(d):
        os.makedirs(d)

def getTarget(fn):
  return fn.replace(HEAD_DIR, OUT_DIR)

def processHtml(fn, tg):
  f = open(fn, 'r')
  content = f.read()
  content = REMOVE_WS(" ", content)
  ensure_dir(tg)
  d = open(tg, 'w+')
  d.write(content)
  content

def processCSS(fn, tg):
  cmd = YUI_COMPRESSOR + fn + ' -o ' + tg
  call(cmd, shell=True)
  return

def processJS(fn, tg):
  cmd = CLOSURE_COMPILER + fn + ' --js_output_file ' + tg
  call(cmd, shell=True)
  return

# Script starts here.
ensure_dir(OUT_DIR)
for root, dirs, files in os.walk(os.getcwd()):
  for dir in dirs:
    print "Processing", os.path.join(root, dir)
  for file in files:
    fn = os.path.join(root) + '/' + file
    if fn.find(OUT_DIR) > 0:
      continue
    tg = getTarget(fn)
    if file.endswith('.html'):
      processHtml(fn, tg)
    if file.endswith('.css'):
      processCSS(fn, tg)
    if file.endswith('.js'):
      processJS(fn, tg)