Извлечение данных из таблицы HTML

Я ищу способ получить определенную информацию из HTML в среде оболочки Linux.

Это немного, что меня интересует:

  • Взаимодействие с bash из python
  • Python - сообщение HTTP из stdin
  • Эмуляция источника Bash в Python
  • Получить статус менеджера активности
  • Почему «#! / Usr / bin / env python» предположительно более корректен, чем просто «#! / Usr / bin / python»?
  • Python subprocess.call - псевдоним bash
  • <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%"> <tr valign="top"> <th>Tests</th> <th>Failures</th> <th>Success Rate</th> <th>Average Time</th> <th>Min Time</th> <th>Max Time</th> </tr> <tr valign="top" class="Failure"> <td>103</td> <td>24</td> <td>76.70%</td> <td>71 ms</td> <td>0 ms</td> <td>829 ms</td> </tr> </table> 

    И я хочу хранить в переменных оболочки или эхо их в парах значений ключей, извлеченных из выше html. Пример :

     Tests : 103 Failures : 24 Success Rate : 76.70 % and so on.. 

    На данный момент я могу создать java-программу, которая будет использовать парсер sax или синтаксический анализатор html, такой как jsoup, для извлечения этой информации.

    Но использование java здесь, по-видимому, накладные расходы, включая runnable jar внутри скрипта «wrapper», который вы хотите выполнить.

    Я уверен, что там должны быть «shell» языки, которые могут делать то же самое: perl, python, bash и т. Д.

    Моя проблема в том, что у меня нет опыта в этом, может кто-нибудь помочь мне решить эту «довольно легкую» проблему

    Быстрое обновление:

    Я забыл упомянуть, что у меня больше таблиц и больше строк в документе .html жаль об этом (ранним утром).

    Обновление № 2:

    Попробовал установить Bsoup как это, так как у меня нет доступа root:

     $ wget http://www.crummy.com/software/BeautifulSoup/bs4/download/4.0/beautifulsoup4-4.1.0.tar.gz $ tar -zxvf beautifulsoup4-4.1.0.tar.gz $ cp -r beautifulsoup4-4.1.0/bs4 . $ vi htmlParse.py # (paste code from ) Tichodromas' answer, just in case this (http://pastebin.com/4Je11Y9q) is what I pasted $ run file (python htmlParse.py) 

    ошибка:

     $ python htmlParse.py Traceback (most recent call last): File "htmlParse.py", line 1, in ? from bs4 import BeautifulSoup File "/home/gdd/setup/py/bs4/__init__.py", line 29 from .builder import builder_registry ^ SyntaxError: invalid syntax 

    Обновление № 3:

    Запуск ответа Tichodromas дает эту ошибку:

     Traceback (most recent call last): File "test.py", line 27, in ? headings = [th.get_text() for th in table.find("tr").find_all("th")] TypeError: 'NoneType' object is not callable 

    есть идеи?

  • Понимание первого аргумента python subprocess.check_output и оболочки = True
  • Изменить рабочий каталог в оболочке с помощью скрипта python
  • Лучший способ сценария установки устройства USB в Linux
  • / usr / bin / ld: не удается найти -lpython2.7
  • OpenCV (через python) в Linux: установить ширину / высоту кадра?
  • Letsencrypt ImportError: без интерфейса имени модуля на amazon linux при обновлении
  • 5 Solutions collect form web for “Извлечение данных из таблицы HTML”

    Решение Python с использованием BeautifulSoup4 ( Edit: с правильным пропуском. Edit3: Использование class="details" для выбора table ):

     from bs4 import BeautifulSoup html = """ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%"> <tr valign="top"> <th>Tests</th> <th>Failures</th> <th>Success Rate</th> <th>Average Time</th> <th>Min Time</th> <th>Max Time</th> </tr> <tr valign="top" class="Failure"> <td>103</td> <td>24</td> <td>76.70%</td> <td>71 ms</td> <td>0 ms</td> <td>829 ms</td> </tr> </table>""" soup = BeautifulSoup(html) table = soup.find("table", attrs={"class":"details"}) # The first tr contains the field names. headings = [th.get_text() for th in table.find("tr").find_all("th")] datasets = [] for row in table.find_all("tr")[1:]: dataset = zip(headings, (td.get_text() for td in row.find_all("td"))) datasets.append(dataset) print datasets 

    Результат выглядит следующим образом:

     [[(u'Tests', u'103'), (u'Failures', u'24'), (u'Success Rate', u'76.70%'), (u'Average Time', u'71 ms'), (u'Min Time', u'0 ms'), (u'Max Time', u'829 ms')]] 

    Edit2: Чтобы создать желаемый результат, используйте что-то вроде этого:

     for dataset in datasets: for field in dataset: print "{0:<16}: {1}".format(field[0], field[1]) 

    Результат:

     Tests : 103 Failures : 24 Success Rate : 76.70% Average Time : 71 ms Min Time : 0 ms Max Time : 829 ms 

    Предполагая, что ваш html-код хранится в файле mycode.html, вот путь bash:

     paste -d: <(grep '<th>' mycode.html | sed -e 's,</*th>,,g') <(grep '<td>' mycode.html | sed -e 's,</*td>,,g') 

    Примечание: выход не идеально выровнен

     undef $/; $text = <DATA>; @tabs = $text =~ m!<table.*?>(.*?)</table>!gms; for (@tabs) { @th = m!<th>(.*?)</th>!gms; @td = m!<td>(.*?)</td>!gms; } for $i (0..$#th) { printf "%-16s\t: %s\n", $th[$i], $td[$i]; } __DATA__ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%"> <tr valign="top"> <th>Tests</th> <th>Failures</th> <th>Success Rate</th> <th>Average Time</th> <th>Min Time</th> <th>Max Time</th> </tr> <tr valign="top" class="Failure"> <td>103</td> <td>24</td> <td>76.70%</td> <td>71 ms</td> <td>0 ms</td> <td>829 ms</td> </tr> </table> 

    выход следующим образом:

     Tests : 103 Failures : 24 Success Rate : 76.70% Average Time : 71 ms Min Time : 0 ms Max Time : 829 ms 

    Решение Python, использующее только стандартную библиотеку (использует тот факт, что HTML является хорошо сформированным XML). Можно обрабатывать более одного ряда данных.

    (Протестировано с Python 2.6 и 2.7. Вопрос был обновлен, говоря, что OP использует Python 2.4, поэтому этот ответ может быть не очень полезен в этом случае. ElementTree был добавлен в Python 2.5)

     from xml.etree.ElementTree import fromstring HTML = """ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%"> <tr valign="top"> <th>Tests</th> <th>Failures</th> <th>Success Rate</th> <th>Average Time</th> <th>Min Time</th> <th>Max Time</th> </tr> <tr valign="top" class="Failure"> <td>103</td> <td>24</td> <td>76.70%</td> <td>71 ms</td> <td>0 ms</td> <td>829 ms</td> </tr> <tr valign="top" class="whatever"> <td>A</td> <td>B</td> <td>C</td> <td>D</td> <td>E</td> <td>F</td> </tr> </table>""" tree = fromstring(HTML) rows = tree.findall("tr") headrow = rows[0] datarows = rows[1:] for num, h in enumerate(headrow): data = ", ".join([row[num].text for row in datarows]) print "{0:<16}: {1}".format(h.text, data) 

    Вывод:

     Tests : 103, A Failures : 24, B Success Rate : 76.70%, C Average Time : 71 ms, D Min Time : 0 ms, E Max Time : 829 ms, F 

    Вот главный ответ, адаптированный для совместимости с Python3, и улучшенный путем удаления пробелов в ячейках:

     from bs4 import BeautifulSoup html = """ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%"> <tr valign="top"> <th>Tests</th> <th>Failures</th> <th>Success Rate</th> <th>Average Time</th> <th>Min Time</th> <th>Max Time</th> </tr> <tr valign="top" class="Failure"> <td>103</td> <td>24</td> <td>76.70%</td> <td>71 ms</td> <td>0 ms</td> <td>829 ms</td> </tr> </table>""" soup = BeautifulSoup(s, 'html.parser') table = soup.find("table") # The first tr contains the field names. headings = [th.get_text().strip() for th in table.find("tr").find_all("th")] print(headings) datasets = [] for row in table.find_all("tr")[1:]: dataset = dict(zip(headings, (td.get_text() for td in row.find_all("td")))) datasets.append(dataset) print(datasets) 
    Python - лучший язык программирования в мире.