Разбор HTML с помощью оболочки
У меня есть HTML с большим количеством данных и интересующей меня части:
<tr valign=top>
<td><b>Total</b></td>
<td align=right><b>54</b></td>
<td align=right><b>1</b></td>
<td align=right>0 (0/0)</td>
<td align=right><b>0</b></td>
</tr>
Я пытаюсь использовать awk
который сейчас:
awk -F "</*b>|</td>" '/<[b]>.*[0-9]/ {print $1, $2, $3 }' "index.html"
но я хочу иметь:
54
1
0
0
Прямо сейчас я получаю:
'<td align=right> 54'
'<td align=right> 1'
'<td align=right> 0'
Какие-либо предложения?
Ответы
Ответ 1
awk -F '[<>]' '/<td / { gsub(/<b>/, ""); sub(/ .*/, "", $3); print $3 } ' file
Вывод:
54
1
0
0
Другой:
awk -F '[<>]' '
/<td><b>Total<\/b><\/td>/ {
while (getline > 0 && /<td /) {
gsub(/<b>/, ""); sub(/ .*/, "", $3)
print $3
}
exit
}' file
Ответ 2
awk
не является парсером HTML. Используйте для этого xpath
или даже xslt
. xmllint
- это инструмент командной строки, способный выполнять запросы XPath и xsltproc
, который может использоваться для выполнения преобразований XSL. Оба инструмента принадлежат пакету libxml2-utils
.
Также вы можете использовать язык программирования, способный анализировать HTML
Ответ 3
Вам действительно нужно использовать какой-то настоящий парсер HTML для этой работы, например:
perl -Mojo -0777 -nlE 'say [split(/\s/, $_->all_text)]->[0] for x($_)->find("td[align=right]")->each'
печатает:
54
1
0
0
Но для этого вам нужно иметь perl и установить Mojolicious package.
(его легко установить с помощью:)
curl -L get.mojolicio.us | sh
Ответ 4
$ awk -F'<td[^>]*>(<b>)?|(</?b>)?</td>' '$2~/[0-9]/{print $2+0}' file
54
1
0
0
Ответ 5
Вы можете использовать htmlutils
для анализа хорошо отформатированных файлов HTML/XML. Пакет включает в себя множество бинарных инструментов для извлечения или изменения данных. Например:
$ curl -s http://example.com/ | hxselect title
<title>Example Domain</title>
Вот пример с предоставленными данными:
$ hxselect -c -s "\n" "td[align=right]" <file.html
<b>54</b>
<b>1</b>
0 (0/0)
<b>0</b>
Вот последний пример с удалением тегов <b>
:
$ hxselect -c -s "\n" "td[align=right]" <file.html | sed "s/<[^>]\+>//g"
54
1
0 (0/0)
0
Для большего количества примеров, проверьте html-xml-utils.
Ответ 6
Для простого извлечения вы можете использовать grep
, например:
-
Ваш пример использования grep
:
$ egrep -o "[0-9][^<]\?\+" file.html
54
1
0 (0/0)
0
и используя ripgrep
:
$ rg -o ">([^>]+)<" -r '$1' <file.html | tail +2
54
1
0 (0/0)
0
-
Извлечение внешнего HTML H1:
$ curl -s http://example.com/ | egrep -o '<h1>.*</h1>'
<h1>Example Domain</h1>
Другие примеры:
-
Извлечение тела:
$ curl -s http://example.com/ | xargs | egrep -o '<body>.*</body>'
<body> <div> <h1>Example Domain</h1> ...
Вместо xargs
вы также можете использовать tr '\n' ' '
.
-
Для нескольких тегов см.: Текст между двумя тегами.
Если вы имеете дело с большими наборами данных, рассмотрите возможность использования ripgrep
который имеет похожий синтаксис, но намного быстрее, чем в Rust.
Ответ 7
Для более сложного анализа вы можете использовать встроенные редакторы, такие как ex/vi, где вы можете переключаться между соответствующими тегами HTML, выбирать/удалять внутренние/внешние теги и редактировать содержимое на месте.
Вот команда:
$ ex +"%s/^[^>].*>\([^<]\+\)<.*/\1/g" +"g/[a-zA-Z]/d" +%p -scq! file.html
54
1
0 (0/0)
0
Вот как работает команда:
-
Используйте ex
-place редактор для замены во всех строках (%
): ex +"%s/pattern/replace/g"
.
Шаблон замещения состоит из 3 частей:
- Выберите от начала строки до
>
(^[^>].*>
) Для удаления, прямо перед 2-й частью. - Выберите нашу основную часть до
<
(([^<]+)
). - Выберите все остальное после
<
для удаления (<.*
). - Мы заменяем всю совпадающую строку на
\1
которая ссылается на шаблон внутри скобок (()
).
-
После подстановки мы удаляем любые буквенно-цифровые строки, используя global: g/[a-zA-Z]/d
.
- Наконец, напечатайте текущий буфер на экране с помощью
+%p
. - Затем молча (
-s
) выйти без сохранения (-c "q!"
) Или сохранить в файл (-c "wq"
).
При тестировании для замены файла на месте измените -scq!
в -scwq
.
Вот еще один простой пример, который удаляет тег стиля из заголовка и печатает проанализированный вывод:
$ curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin
Тем не менее, не рекомендуется использовать регулярные выражения для анализа вашего HTML, поэтому для долгосрочного подхода вы должны использовать соответствующий язык (например, Python, Perl или PHP DOM).
Смотрите также: