Самый быстрый, простой и лучший способ для анализа таблицы HTML? - PullRequest
9 голосов
/ 04 февраля 2011

Я пытаюсь перевести эту таблицу http://www.datamystic.com/timezone/time_zones.html в формат массива, чтобы я мог делать с ней все, что захочу. Желательно в PHP, Python или JavaScript.

Эта проблема часто возникает, поэтому вместо того, чтобы искать помощь по этой конкретной проблеме, я ищу идеи, как решить все подобные проблемы.

BeautifulSoup - это первое, что приходит на ум. Другая возможность - скопировать / вставить его в TextMate, а затем запустить регулярные выражения.

Что вы предлагаете?

Это сценарий, который я закончил писать, но, как я уже сказал, я ищу более общее решение.

from BeautifulSoup import BeautifulSoup
import urllib2


url = 'http://www.datamystic.com/timezone/time_zones.html';
response = urllib2.urlopen(url)
html = response.read()
soup = BeautifulSoup(html)
tables = soup.findAll("table")
table = tables[1]
rows = table.findAll("tr")
for row in rows:
    tds = row.findAll('td')
    if(len(tds)==4):
        countrycode = tds[1].string
        timezone = tds[2].string
        if(type(countrycode) is not type(None) and type(timezone) is not type(None)):
            print "\'%s\' => \'%s\'," % (countrycode.strip(), timezone.strip())

Комментарии и предложения по улучшению моего кода на Python тоже приветствуются;)

Ответы [ 5 ]

5 голосов
/ 04 февраля 2011

Для вашей общей проблемы: попробуйте lxml.html из пакета lxml (представьте его как stdlibs xml.etree на стероидах: тот же xml api, но с поддержкой html, xpath, xslt и т. д.)

Быстрый пример для вашего конкретного случая:

from lxml import html

tree = html.parse('http://www.datamystic.com/timezone/time_zones.html')
table = tree.findall('//table')[1]
data = [
           [td.text_content().strip() for td in row.findall('td')] 
           for row in table.findall('tr')
       ]

Это даст вам вложенный список: каждый подсписок соответствует строке втаблица и содержит данные из ячеек.Скрытно вставленные рекламные строки еще не отфильтрованы, но это должно помочь вам в этом.(и между прочим: lxml - это быстро!)

НО: более конкретно для вашего конкретного случая использования: есть лучший способ получить в базе данных часовых поясов информацию, чем очистка этой конкретной веб-страницы (в сторону): обратите внимание, что на веб-странице фактически упоминается, что вы не можете копировать ее содержимое).Есть даже существующие библиотеки, которые уже используют эту информацию, см., Например, python-dateutil .

4 голосов
/ 04 февраля 2011

Избегайте регулярных выражений для разбора HTML, они просто не подходят для него, вам нужен DOM-парсер, например BeautifulSoup, наверняка ...

Несколько других альтернатив

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

0 голосов
/ 10 декабря 2018

Пока мы строили SerpAPI , мы протестировали много платформ / анализаторов.

Вот результат теста для Python.

Более подробная информация о Среде: https://medium.com/@vikoky/fastest-html-parser-available-now-f677a68b81dd

0 голосов
/ 04 февраля 2011

Эффективность регулярного выражения превосходит синтаксический анализатор DOM.

Посмотрите на это сравнение:

http://www.rockto.com/launcher/28852/mochien.com/Blog/Read/A300111001736/Regex-VS-DOM-untuk-Rockto-Team

Вы можете найти много других в Интернете.

0 голосов
/ 04 февраля 2011

Я предлагаю загрузить документ с помощью синтаксического анализатора XML, такого как DOMDocument :: loadHTMLFile, который поставляется в комплекте с PHP, а затем использовать XPath для получения необходимых данных.

Это не самый быстрый способ, но самый читаемый (на мой взгляд) в итоге. Вы можете использовать Regex, который, вероятно, будет немного быстрее, но будет плохим стилем (трудно отлаживать, трудно читать).

РЕДАКТИРОВАТЬ: На самом деле это сложно, потому что упомянутая вами страница не является допустимым HTML (см. Validator.w3.org). Особенно мешают теги без открывающих / закрывающих тегов.

Похоже, что xmlstarlet (http://xmlstar.sourceforge.net/ (отличный инструмент)) способен устранить проблему (запустите xmlstarlet fo -R). xmlstarlet также может выполнять сценарии xpath и xslt, которые помогут вам извлечь данные с помощью простого сценария оболочки.

...