Анализ данных фиксированного формата, встроенных в HTML, в Python

StackOverflow https://stackoverflow.com/questions/409769

Вопрос

Я использую Appengine API Google.

from google.appengine.api import urlfetch

для получения веб-страницы.Результат

result = urlfetch.fetch("http://www.example.com/index.html")

— это строка содержимого html (в result.content).Проблема в том, что данные, которые я хочу проанализировать, на самом деле не в форме HTML, поэтому я не думаю, что использование HTML-парсера Python мне подойдет.Мне нужно проанализировать весь простой текст в теле html-документа.Единственная проблема заключается в том, что urlfetch возвращает одну строку всего HTML-документа, удаляя все символы новой строки и лишние пробелы.

РЕДАКТИРОВАТЬ:Хорошо, я попытался получить другой URL-адрес, и, судя по всему, urlfetch не удаляет символы новой строки, это была исходная веб-страница, которую я пытался проанализировать, и которая таким образом обрабатывала HTML-файл...КОНЕЦ РЕДАКТИРОВАНИЯ

Если документ выглядит примерно так:

<html><head></head><body>
AAA 123 888 2008-10-30 ABC
BBB 987 332 2009-01-02 JSE
...
A4A       288        AAA
</body></html>

result.content будет таким, после того как urlfetch его получит:

'<html><head></head><body>AAA 123 888 2008-10-30 ABCBBB 987     2009-01-02 JSE...A4A     288            AAA</body></html>'

Использование анализатора HTML не поможет мне с данными между тегами тела, поэтому я собирался использовать регулярные выражения для анализа моих данных, но, как вы можете видеть, последняя часть одной строки объединяется с первой частью следующей строки. , и я не знаю, как его разделить.Я пытался

result.content.split('\n')

и

result.content.split('\r')

но полученный список состоял всего из одного элемента.Я не вижу никаких опций в функции urlfetch Google, чтобы не удалять символы новой строки.

Есть идеи, как я могу проанализировать эти данные?Может быть, мне нужно получить его по-другому?

Заранее спасибо!

Это было полезно?

Решение

Я понимаю, что формат документа соответствует тому, который вы опубликовали.В этом случае я согласен, что парсер типа Красивый суп может быть не лучшим решением.

Я предполагаю, что вы уже получаете интересные данные (между тегами BODY) с помощью регулярного выражения типа

import re
data = re.findall('<body>([^\<]*)</body>', result)[0]

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

start = 0
end = 5
while (end<len(data)):
   print data[start:end]
   start = end+1
   end = end+5
print data[start:]

(примечание:Я не проверял этот код на наличие граничных случаев и ожидаю, что он потерпит неудачу.Это здесь только для того, чтобы показать общую идею)

Другие советы

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

Если вы контролируете исходные данные, поместите их в текстовый файл, а не в HTML.

Если у вас есть основной текст в виде одной длинной строки, вы можете разбить его следующим образом.Предполагается, что каждая запись состоит из 26 символов.

body= "AAA 123 888 2008-10-30 ABCBBB 987     2009-01-02 JSE...A4A     288            AAA"
for i in range(0,len(body),26):
    line= body[i:i+26]
    # parse the line

РЕДАКТИРОВАТЬ:Понимание прочитанного – желательная вещь.Я упустил момент, когда строки соединяются вместе без разделителя между ними, в этом и был весь смысл, не так ли?Так что, не обращайте внимания на мой ответ, он на самом деле не имеет значения.


Если вы знаете, что каждая строка состоит из пяти столбцов, разделенных пробелами, то (после того, как вы удалили HTML) вы могли бы сделать что-то вроде (непроверено):

def generate_lines(datastring):
    while datastring:
        splitresult = datastring.split(' ', 5)
        if len(splitresult) >= 5:
            datastring = splitresult[5]
        else:
            datastring = None
        yield splitresult[:5]

for line in generate_lines(data):
    process_data_line(line)

Конечно, вы можете изменить символ разделения и количество столбцов по мере необходимости (возможно, даже передав их в функцию генератора в качестве дополнительных параметров) и при необходимости добавить обработку ошибок.

Дальнейшие предложения по разбиению строки s на блоки по 26 символов:

В виде списка:

>>> [s[x:x+26] for x in range(0, len(s), 26)]
['AAA 123 888 2008-10-30 ABC',
 'BBB 987     2009-01-02 JSE',
 'A4A     288            AAA']

В качестве генератора:

>>> for line in (s[x:x+26] for x in range(0, len(s), 26)): print line
AAA 123 888 2008-10-30 ABC
BBB 987     2009-01-02 JSE
A4A     288            AAA

Заменять range() с xrange() в Python 2.x, если s очень длинный.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top