- Вопрос или проблема
- портативность
- Обработка протокола HTTP и редиректов
- Производительность/Эффективность
- Парсинг HTML
- интерпретация кода внутри тегов.
- Набор символов
- В общем
- Пример
- Подробности
- Более сложные ситуации
- Пример
- lang=…
- Реальный HTML/XML Парсер – на Ruby
- Реальный HTML/XML Парсер – на Perl
- Ответ или решение
- Использование wget и perl
- Использование curl и grep
- Использование Python с библиотекой BeautifulSoup
- Использование xidel
- Установка и настройка
- Заключение
Вопрос или проблема
Я ищу командную программу, которая печатает заголовок веб-страницы. Например:
title-fetcher 'https://www.youtube.com/watch?v=Dd7dQh8u4Hc'
…должно получиться:
Почему плохие слова плохие?
Вы даете URL-адрес, программа выводит заголовок.
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Вы можете отправить его на ввод в GNU recode
, если в нем есть что-то вроде <
:
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' |
recode html..
Чтобы убрать часть - youtube
:
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)(?: - youtube)?\s*<\/title/si'
Чтобы указать на некоторые ограничения:
портативность
Нет стандартной/портативной команды для выполнения HTTP-запросов. Несколько десятилетий назад, я бы рекомендовал использовать lynx -source
вместо этого. Но в наши дни, wget
более портативен, так как он может быть найден по умолчанию на большинстве систем GNU (включая большинство операционных систем на основе Linux). Другие довольно портативные включают команду GET
, которая приходит с libwww perl
, который часто установлен, lynx -source
, и в меньшей степени curl
. Другие общие включают links -source
, elinks -source
, w3m -dump_source
, lftp -c cat
…
Обработка протокола HTTP и редиректов
wget
может получить не ту страницу, которую, например, покажет firefox
. Причиной является то, что HTTP-серверы могут выбирать отправлять другую страницу на основе информации, предоставленной в запросе от клиента.
Запрос, отправленный wget/w3m/GET… будет отличаться от того, который отправит firefox. Если это проблема, вы можете изменить поведение wget
, чтобы изменить способ отправки запроса, используя параметры.
Наиболее важными в этом отношении здесь являются:
Accept
иAccept-language
: они говорят серверу, на каком языке и в какой кодировке клиент хотел бы получить ответ.wget
по умолчанию не отправляет никаких, поэтому сервер обычно отправляет его с настройками по умолчанию.firefox
, с другой стороны, вероятно настроен запрашивать ваш язык.User-Agent
: идентифицирует клиентское приложение для сервера. Некоторые сайты отправляют различный контент в зависимости от клиента (хотя это в основном для различий между интерпретациями языка javascript) и могут отказать в обслуживании, если вы используете user agent типа робота, как напримерwget
.Cookie
: если вы посещали этот сайт ранее, ваш браузер может иметь постоянные cookies для него.wget
этого не сделает.
wget
будет следовать редиректам, когда они выполняются на уровне протокола HTTP, но так как он не просматривает содержимое страницы, не будет следовать за теми, которые выполнены с помощью javascript или таких вещей как <meta http-equiv="refresh" content="0; url=http://example.com/">
.
Производительность/Эффективность
Здесь, из-за лени, мы заставляем perl
прочитать весь контент в память, прежде чем приступить к поиску тега <title>
. Учитывая, что заголовок находится в разделе <head>
, который находится в первых байтах файла, это не оптимально. Лучшый подход, если GNU awk
доступен на вашей системе, может быть:
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
gawk -v IGNORECASE=1 -v RS='</title' 'RT{gsub(/.*<title[^>]*>/,"");print;exit}'
Таким образом, awk останавливает чтение после первого вхождения </title
, и, выходя, заставляет wget
прекратить загрузку.
Парсинг HTML
Здесь wget
записывает страницу, как только она загружается. В то же время perl
проглатывает его вывод (-0777 -n
) целиком в память и затем выводит HTML-код, найденный между первыми вхождениями <title...>
и </title
.
Это будет работать для большинства HTML-страниц, которые имеют тег <title>
, но есть случаи, когда это не сработает.
В отличие от решения coffeeMug, оно будет парсить HTML-страницу как XML и возвращать соответствующее значение для title
. Оно более корректно, если страница гарантированно является правильным XML. Однако HTML не требуется быть правильным XML (старые версии языка такими не были), и поскольку большинство браузеров допускают некорректный HTML-код, там даже много неверного HTML-кода.
И мое решение, и решение coffeeMug будет давать сбой в различных пограничных случаях, иногда одинаковые, иногда нет.
Например, мое не сработает на:
<html><head foo="<title>"><title>blah</title></head></html>
или:
<!-- <title>old</title> --><title>new</title>
Тогда как его не сработает на:
<TITLE>foo</TITLE>
(действительный html, не xml) или:
или:
<title>...</title>
...
<script>a="<title>"; b='</title>';</script>
(снова, действительный html
, отсутствуют части <![CDATA[
, чтобы сделать его правильным XML).
<title>foo <<<bar>>> baz</title>
(неправильный html, но все же встречается и поддерживается большинством браузеров)
интерпретация кода внутри тегов.
Это решение выводит необработанный текст между <title>
и </title>
. Обычно там не должно быть никаких HTML-тегов, возможно, есть комментарии (хотя некоторые браузеры, как firefox, их не обрабатывают, поэтому очень маловероятно). Тем не менее, может быть некоторая кодировка HTML:
$ wget -qO- 'http://www.youtube.com/watch?v=CJDhmlMQT60' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Wallace & Gromit - The Cheesesnatcher Part 1 (claymation) - YouTube
Что обрабатывается GNU recode
:
$ wget -qO- 'http://www.youtube.com/watch?v=CJDhmlMQT60' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' |
recode html..
Wallace & Gromit - The Cheesesnatcher Part 1 (claymation) - YouTube
Но веб-клиент также должен сделать больше преобразований этого кода при отображении заголовка (например, сжать некоторые из пробелов, удалить начальные и конечные). Тем не менее, маловероятно, что это потребуется. Таким образом, как в других случаях, вам решать, стоит ли это усилий.
Набор символов
До UTF-8 iso8859-1 был предпочтительным набором символов в Интернете для не-ASCII символов, хотя, строго говоря, они должны быть записаны как é
. Более поздние версии HTTP и языка HTML добавили возможность указывать набор символов в заголовках HTTP или в заголовках HTML, и клиент может указать предпочитаемые наборы символов. В наши дни UTF-8, как правило, является набором символов по умолчанию.
Таким образом, это означает, что там вы найдете é
, написанное как é
, как é
, как UTF-8 é
, (0xc3 0xa9), как iso-8859-1 (0xe9), причем для последних 2 иногда информация о наборе символов в заголовках HTTP или заголовках HTML (в различных форматах), иногда нет.
wget
получает только сырые байты, его не интересует их значение как символов, и он не сообщает веб-серверу о предпочитаемом наборе символов.
recode html..
позаботится о преобразовании é
или é
в правильную последовательность байтов для используемого на вашей системе набора символов, но в остальном это более сложно.
Если ваш системный набор символов — utf-8, скорее всего, это будет в порядке в большинстве случаев, так как это, как правило, используется в качестве набора символов по умолчанию.
$ wget -qO- 'http://www.youtube.com/watch?v=if82MGPJEEQ' |
perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
Noir Désir - L'appartement - YouTube
Это é
выше было UTF-8 é
.
Но если вы хотите учесть другие наборы символов, в очередной раз, это придется учесть.
Следует также отметить, что это решение не будет работать вообще для страниц, закодированных с использованием UTF-16 или UTF-32.
В общем
Идеально, то, что вам здесь нужно, это настоящий веб-браузер, чтобы получить информацию. То есть вам нужно что-то, чтобы сделать HTTP-запрос с правильными параметрами, правильно интерпретировать HTTP-ответ, полностью интерпретировать HTML-код как это сделает браузер, и вернуть заголовок.
Так как я не думаю, что это может быть сделано из командной строки с браузерами, которые я знаю (хотя см. теперь этот трюк с lynx
), вам придется прибегнуть к эвристикам и приближениям, и то, что выше, так хорошо, как и любое другое.
Вы также, возможно, захотите учесть производительность, безопасность… Например, чтобы охватить все случаи (например, веб-страница, которая имеет некоторый javascript, загруженный из сайта третьей стороны, который устанавливает заголовок или перенаправляет на другую страницу в onload hook), вам, возможно, придется реализовать настоящий браузер с его движком dom и javascript, который, возможно, совершает сотни запросов для одной HTML-страницы, некоторые из которых пытаются воспользоваться уязвимостями…
Хотя использование регулярных выражений для разбора HTML часто считается неправильным, вот типичный случай, когда это достаточно для задачи (на мой взгляд).
Вы также можете попробовать hxselect
(из HTML-XML-Utils) с wget
следующим образом:
wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' | hxselect -s '\n' -c 'title' 2>/dev/null
Вы можете установить hxselect
в Debian-основанных дистрибутивах, используя:
sudo apt-get install html-xml-utils
.
Перенаправление STDERR для предотвращения сообщения Input is not well-formed. (Maybe try normalize?)
.
Чтобы избавиться от “- YouTube”, направьте вывод приведенной выше команды на awk '{print substr($0, 0, length($0)-10)}'
.
Вы также можете использовать curl
и grep
, чтобы сделать это. Вам понадобится использовать PCRE (Perl-совместимые регулярные выражения) в grep
, чтобы получить возможности lookbehind и lookahead для нахождения тегов <title>...</title>
.
Пример
$ curl 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -so - | \
grep -iPo '(?<=<title>)(.*)(?=</title>)'
Почему плохие слова плохие? - YouTube
Подробности
Параметры curl
:
-s
= тихий режим-o -
= отправить вывод на STDOUT
Параметры grep
:
-i
= без учета регистра-o
= вернуть только совпавшую часть-P
= режим PCRE
Шаблон для grep
:
(?<=<title>)
= искать строку, которая начинается с этого слева(?=</title>)
= искать строку, которая заканчивается с этим справа(.*)
= все, что между<title>..</title>
.
Более сложные ситуации
Если <title>...</titie>
занимает несколько строк, то вышеуказанное не найдет его. Вы можете уменьшить эту ситуацию, используя tr
, чтобы удалить любые символы \n
, например, tr -d '\n'
.
Пример
Пример файла.
$ cat multi-line.html
<html>
<title>
это \n заголовок
</TITLE>
<body>
<p>это \n заголовок </p>
</body>
</html>
И пример выполнения:
$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
tr -d '\n' | \
grep -iPo '(?<=<title>)(.*)(?=</title>)'
это \n заголовок
lang=…
Если <title>
установлен так: <title lang="en">
, то перед использованием grep
вам нужно будет удалить это. Инструмент sed
можно использовать для этого:
$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
tr -d '\n' | \
sed 's/ lang="\w+"//gi' | \
grep -iPo '(?<=<title>)(.*)(?=</title>)'
это \n заголовок
Выше находит строку lang=
(без учета регистра), за которой следует последовательность слов (\w+
). Затем она удаляется.
Реальный HTML/XML Парсер – на Ruby
На определенном этапе регулярные выражения будут не в состоянии решить эту проблему. Если это произойдет, вам, вероятно, понадобится использовать реальный HTML/XML-парсер. Один такой парсер – Nokogiri. Он доступен в Ruby как Gem и может использоваться следующим образом:
$ curl 'http://www.jake8us.org/~sam/multi-line.html' -so - | \
ruby -rnokogiri -e \
'puts Nokogiri::HTML(readlines.join).xpath("//title").map { |e| e.content }'
это \n заголовок
Вышеприведенное парсит данные, которые приходят через curl
как HTML (Nokogiri::HTML
). Метод xpath
затем ищет узлы (теги) в HTML, которые являются конечными узлами, (//
) с именем title
. Для каждого найденного тега мы хотим вернуть его содержимое (e.content
). Потом puts
выводит их.
Реальный HTML/XML Парсер – на Perl
Вы также можете сделать что-то похожее на Perl и модуль HTML::TreeBuilder::XPath.
$ cat title_getter.pl
#!/usr/bin/perl
use HTML::TreeBuilder::XPath;
$tree = HTML::TreeBuilder::XPath->new_from_url($ARGV[0]);
($title = $tree->findvalue('//title')) =~ s/^\s+//;
print $title . "\n";
Вы можете затем запустить этот скрипт следующим образом:
$ ./title_getter.pl http://www.jake8us.org/~sam/multi-line.html
это \n заголовок
Использовать простую регекс для разбора HTML наивно. Например, с новыми строками и игнорируя специальную кодировку символов, указанную в файле. Сделайте правильную вещь и действительно проанализируйте страницу, используя любой из других настоящих парсеров, упомянутых в других ответах, или используйте следующий однострочник:
python -c "import bs4, urllib2; print(bs4.BeautifulSoup(urllib2.urlopen('http://www.crummy.com/software/BeautifulSoup/bs4/doc/')).title.text)"
(Приведенное выше включает символ Unicode).
BeautifulSoup также обрабатывает много некорректного HTML (например, отсутствующие закрывающие теги), что полностью выбило бы из строя простое регулярное выражение. Вы можете установить его в стандартный python используя:
pip install beautifulsoup4
или, если у вас нет pip
, с
easy_install beautifulsoup4
Некоторые операционные системы, такие как Debian/Ubuntu, также упаковывают его (python-bs4
пакет в Debian/Ubuntu).
Простой способ:
curl -s example.com | grep -o "<title>[^<]*" | tail -c+8
Несколько альтернатив:
curl -s example.com | grep -o "<title>[^<]*" | cut -d'>' -f2-
wget -qO- example.com | grep -o "<title>[^<]*" | sed -e 's/<[^>]*>//g'
Может быть, это “чит”, но одним из вариантов является pup, командный парсер HTML.
Вот два способа сделать это:
Использование поля meta
с атрибутом property="og:title
$ wget -q 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -O - | \
> pup 'meta[property=og:title] attr{content}'
Почему плохие слова плохие?
и еще один способ использовать поле title
напрямую (и затем обрезать строку - YouTube
в конце).
$ wget -q 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' -O - | \
> pup 'title text{}' | sed 's/ - YouTube$//'
Почему плохие слова плохие?
Похоже, это возможно с lynx
, используя этот трюк:
lynx 3>&1 > /dev/null -nopause -noprint -accept_all_cookies \
-cmd_script /dev/stdin<<'EOF' 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc'
set PRINTER=P:printf '%0s\\n' "$LYNX_PRINT_TITLE">&3:TRUE
key p
key Select key
key ^J
exit
EOF
Поскольку это реальный веб-браузер, он не страдает от многих из ограничений, которые я упоминал в своем другом ответе.
Здесь мы используем то, что lynx
устанавливает переменную среды $LYNX_PRINT_TITLE
при печати страницы.
Выше мы используем lynx
скриптовую возможность (со скриптом, переданным на stdin через herodocument), чтобы:
- определить “принтер” lynx, называемый
P
, который просто выводит содержимое этой переменной на файловый дескриптор3
(этот файловый дескриптор перенаправляется на стандартный выводlynx
с помощью3>&1
, в то время как стандартный вывод lynx перенаправляется на /dev/null). - симулировать нажатие пользователем p и End (также известная как Select), и Enter (
^J
).
Пример на Python 3 + BeautifulSoup может выглядеть так:
python3 -c "import bs4, requests; print(bs4.BeautifulSoup(requests.get('https://example.com/').content).title.text)"
Используя htmlq
:
curl --silent "https://www.youtube.com/watch?v=Dd7dQh8u4Hc" | htmlq --text title
Если у вас не установлен, htmlq
можно собрать с cargo:
cargo install htmlq
Мне понравилась идея Стефана Чазела использовать Lynx и LYNX_PRINT_TITLE, но этот скрипт у меня не работал на Ubuntu 14.04.5.
Я сделал упрощенную версию, запустив Lynx и используя предварительно настроенные файлы.
Добавьте следующую строку в /etc/lynx-cur/lynx.cfg (или в любое место, где находится ваш lynx.cfg):
PRINTER:P:printenv LYNX_PRINT_TITLE>/home/account/title.txt:TRUE:1000
Эта строка инструктирует сохранить заголовок при печати в “/home/account/title.txt” – вы можете выбрать любое имя файла. Вы запрашиваете ОЧЕНЬ большие страницы, увеличьте вышеуказанное значение “1000” до любого количества строк на страницу, которое вы хотите, иначе Lynx сделает дополнительный запрос “при печати документа, содержащего очень большое количество страниц”.
Затем создайте файл /home/account/lynx-script.txt со следующим содержимым:
key p
key Select key
key ^J
exit
Затем запустите Lynx, используя следующие параметры командной строки:
lynx -term=vt100 -display_charset=utf-8 -nopause -noprint -accept_all_cookies -cmd_script=/home/account/lynx-script.txt "http://www.youtube.com/watch?v=Dd7dQh8u4Hc" >/dev/nul
По завершении этой команды будет создан файл /home/account/title.txt с заголовком вашей страницы.
Коротко говоря, вот функция на PHP, которая возвращает заголовок страницы по заданному URL, или false в случае ошибки.
function GetUrlTitle($url)
{
$title_file_name = "/home/account/title.txt";
if (file_exists($title_file_name)) unlink($title_file_name); // удаляет файл, если он существует
$cmd = '/usr/bin/lynx -cfg=/etc/lynx-cur/lynx.cfg -term=vt100 -display_charset=utf-8 -nopause -noprint -accept_all_cookies -cmd_script=/home/account/lynx-script.txt "'.$url.'"';
exec($cmd, $output, $retval);
if (file_exists($title_file_name))
{
$title = file_get_contents($title_file_name);
unlink($title_file_name); // удаляет файл после чтения
return $title;
} else
{
return false;
}
}
print GetUrlTitle("http://www.youtube.com/watch?v=Dd7dQh8u4Hc");
Используя nokogiri, можно использовать простую CSS-запрос для извлечения внутреннего текста тега :
$ nokogiri -e 'puts $_.ат_css("title").content'
Почему плохие слова плохие? - YouTube
Точно так же, чтобы извлечь значение атрибута “content” тега :
$ nokogiri -e 'puts $_.ат_css("meta[name=title]").attr("content")'
Почему плохие слова плохие?
Используя Raku (ранее известный как Perl_6)
Перевод принятого ответа на Perl (выше) в Raku:
~$ wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
raku -e 'given slurp() { put $/ if m:g[ \<title .*? \> .+? \<\/title\> ] };'
<title>Почему плохие слова плохие? - YouTube</title>
ИЛИ (то же самое, но без тегов):
~$ wget -qO- 'http://www.youtube.com/watch?v=Dd7dQh8u4Hc' |
raku -e 'given slurp() { put $0 if m[ \<title .*? \> (.+?) \<\/title\> ] };'
Почему плохие слова плохие? - YouTube
Метод/функция Raku slurp()
буквально глотает весь файл в память — с новыми строками и всем остальным. В Raku регекс .
“любой-символ” включает новую строку, так что можно успешно извлечь теги заголовка, которые занимают несколько строк. (Есть место для улучшения: в Raku, используя lines.join(" ")
вместо slurp()
, в новой строке будет переведено \n
в
пробел, что сэкономит шаг перевода позже).
Используя HTTP::UserAgent
и HTML::Parser::XML
модули Raku:
use HTTP::UserAgent;
use HTML::Parser::XML;
#Код HTTP::UserAgent:
my $ua-client = HTTP::UserAgent.new(); $ua-client.timeout = 10;
my $response = $ua-client.get('http://www.youtube.com/watch?v=Dd7dQh8u4Hc');
die "unsuccessful" unless $response.is-success ;
#say ~$response.header;
#say ~$response.content;
#Код HTML::Parser::XML:
my $parser = HTML::Parser::XML.new;
my $xmldoc = $parser.parse($response.content);
for $xmldoc.getElementsByTagName("title") {.contents.put};
Используя модули Cro::HTTP::Client
и HTML::Parser::XML
Raku:
use Cro::HTTP::Client;
#use Cro::HTTP::BodyParsers;
use HTML::Parser::XML;
#Код Cro::HTTP::Client:
my $client = Cro::HTTP::Client.new(
headers => [ User-agent => 'Cro'],
#add-body-parsers => [ HTML::Parser::XML ],
);
my $response = await $client.get('http://www.youtube.com/watch?v=Dd7dQh8u4Hc');
#say ~$response;
my Str $body_text1 = await $response.body-text();
#say $body_text1;
#Код HTML::Parser::XML:
my $parser = HTML::Parser::XML.new;
my $xmldoc = $parser.parse($body_text1);
for $xmldoc.getElementsByTagName("title") {.contents.put};
Оба скрипта возвращают Почему плохие слова плохие? - YouTube
†. Оба скрипта могут возвращать требуемый title
, преобразуя контент/тело в .Str
и используя регулярное выражение (после кода вверху). Однако более элегантный/эффективный способ — это разбор content
/body
, используя парсер XML
, поставляемый модулем HTML::Parser::XML
Raku. (Заметьте: версия , использует Promises для выполнения запросов клиента, и в некоторых случаях следует использовать модуль Cro::HTTP::BodyParsers
).
Наконец, в качестве альтернативы разбору $response
(который вызывает модуль XML
Raku под капотом) методом HTML::Parser::XML
, можно вместо этого использовать разбор XML с помощью модуля DOM::Tiny
Raku. Для чего-либо одного из приведенных выше скриптов, замените, добавив линию use DOM::Tiny;
в верхней части, и следующий блок кода внизу:
use DOM::Tiny;
my $dom = DOM::Tiny.parse($response.content.Str); #Используйте вместе с HTTP::UserAgent script
#ИЛИ
my $dom = DOM::Tiny.parse($body_text1); #Используйте с Cro::HTTP::Client script
#ПОТОМ
my $title = $dom.at('title').text;
.put for $title;
С использованием кода DOM::Tiny
выводится текст заголовка Почему плохие слова плохие? - YouTube
(никакого регулярного выражения не требуется).
† Экосистема Raku имеет и другие клиентские модули для HTTP, включая HTTP::Tiny
и HTTP::Tinyish
.
https://raku.land/github:sergot/HTTP::UserAgent
https://github.com/sergot/http-useragent
https://raku.land/zef:cro/Cro::HTTP
https://cro.services/docs/reference/cro-http-client
https://raku.land/cpan:HANENKAMP/DOM::Tiny
https://github.com/zostay/raku-DOM-Tiny
https://raku.org/
Используя xidel:
$ xidel -s http://www.youtube.com/watch?v=Dd7dQh8u4Hc --css title
Почему плохие слова плохие? - YouTube
При необходимости, apt install xidel
или аналогичное.
Ответ или решение
Для извлечения заголовка веб-страницы с использованием командной строки есть несколько методов, которые могут быть полезны в зависимости от вашего окружения и предпочтений. Давайте рассмотрим различные подходы с учетом специфических особенностей и возможностей.
Использование wget
и perl
Средства: wget
, perl
, и опционально recode
.
Пример команды:
wget -qO- 'https://www.example.com' | perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title>/si' | recode html..
Преимущества:
- Доступно в большинстве Linux-систем по умолчанию.
- Простота в использовании и настройке.
Недостатки:
wget
может не отображать страницу так же, как это делают современные браузеры из-за различий в обработке HTTP-запросов.- Регулярные выражения (
perl
) могут быть ненадежны при работе с некорректным HTML.
Использование curl
и grep
Средства: curl
, grep
.
Пример команды:
curl -s 'https://www.example.com' | grep -oP '(?<=<title>)(.*)(?=</title>)'
Преимущества:
- Широкая поддержка на различных платформах.
- Простота и быстрота.
Недостатки:
- Может не справляться с многострочными тегами.
Использование Python с библиотекой BeautifulSoup
Средства: Python, BeautifulSoup (bs4).
Пример команды:
python3 -c "import requests, bs4; print(bs4.BeautifulSoup(requests.get('https://www.example.com').content, 'html.parser').title.text)"
Преимущества:
- Надежность при работе с некорректным HTML.
- Хорошая поддержка Unicode и различных кодировок.
Недостатки:
- Требуется предварительная установка Python и библиотеки BeautifulSoup.
Использование xidel
Средства: xidel
.
Пример команды:
xidel -s 'https://www.example.com' --css title
Преимущества:
- Инструмент специально создан для работы с XML и HTML.
- Легкость использования для извлечения данных с помощью CSS-селекторов.
Недостатки:
- Менее распространен, может потребовать установки.
Установка и настройка
Для использования вышеупомянутых инструментов может потребоваться установка дополнительных зависимостей или программного обеспечения. Например, BeautifulSoup
можно установить с помощью команды pip install beautifulsoup4
, а xidel
можно установить посредством менеджера пакетов вашего дистрибутива.
Заключение
Каждое из решений имеет свои особенности и подходит для различных сценариев. При выборе ссылки на команду или инструмент учтите требования к вашей системе, доступные ресурсы и сложность реализации. Это позволит вам извлекать заголовки веб-страниц эффективно и надежно.