2016-10-13 4 views
0

EDIT: Теперь, когда проблема решена, я понимаю, что она больше связана с правильным чтением/записью байтовых строк, а не с HTML. Надеюсь, это поможет кому-то еще найти этот ответ.Каков правильный метод чтения и записи HTML/XML (байтовая строка) с Python и lxml и etree?

У меня есть HTML-файл, который плохо отформатирован. Я хочу использовать Python lib, чтобы просто сделать его аккуратным.

Похоже, что это должно быть так же просто, как:

import sys 
from lxml import etree, html 

#read the unformatted HTML 
with open('C:/Users/mhurley/Portable_Python/notebooks/View_Custom_Report.html', 'r', encoding='utf-8') as file: 
    #write the pretty XML to a file 
    file_text = ''.join(file.readlines()) 

#format the HTML 
document_root = html.fromstring(file_text) 
document = etree.tostring(document_root, pretty_print=True) 

#write the nice, pretty, formatted HTML 
with open('C:/Users/mhurley/Portable_Python/notebooks/Pretty.html', 'w') as file: 
    #write the pretty XML to a file 
    file.write(document) 

Но этот кусок кода жалуется, что file_lines не является строкой или байт-подобный объект. Хорошо, имеет смысл, что функция не может взять список, я полагаю.

Но тогда это «байты» не строка. Нет проблем, str(document)

Но тогда я получаю HTML, полный '\ n', которые не являются символами новой строки ... они являются косой чертой, сопровождаемой en. И нет фактических возвратов каретки в результате, это всего лишь одна длинная линия.

Я пробовал ряд других странных вещей, таких как указание кодировки, попытка декодирования и т. Д. Ни один из которых не дает желаемого результата.

Каков правильный способ читать и писать этот вид (это не ASCII правильный термин?) Текст?

ответ

1

Вам не хватает того, что вы получаете байты из метода tostring из etree и должны учитывать это при записи (bytestring) в файл. Используйте b переключатель в функции open, как это и забыть о str() преобразования:

with open('Pretty.html', 'wb') as file: 
    #write the pretty XML to a file 
    file.write(document) 

Добавлением

Несмотря на то, что этот ответ решает непосредственную проблему под руку, и учит о байтовых строках, то solution от Padraic Cunningham - это более чистый и быстрый способ записи lxml etrees в файл.

+0

Я заметил, что тоже, но остается вопрос: как я могу заставить его НЕ «оказывать смешно», когда я пишу в файл? – Matt

+0

Отлично! Благодаря! Я понятия не имел, что «wb» - это допустимый режим для записи файлов. Это прекрасно работает. – Matt

+0

... что, вероятно, также объясняет, почему мой выходной файл начинался с «b» и был полностью заключен в набор одиночных кавычек. Я думал, что это странно, но я не думал, что это имеет смысл. – Matt

1

Это можно сделать все с помощью LXML в пару строк кода, не возникает необходимости использовать открытый метод .WRITE именно за то, что вы пытаетесь сделать:

# parse using file name which is the also the recommended way. 
tree = html.parse("C:/Users/mhurley/Portable_Python/notebooks/View_Custom_Report.html") 
# call write on the tree 
tree.write("C:/Users/mhurley/Portable_Python/notebooks/Pretty.html", pretty_print=True, encoding="utf=8") 

также file_text = ''.join(file.readlines()) точно так же, как и file_text = file.read()