2009-12-10 5 views
45

Я хочу извлечь URL-адрес из тегов привязки html-файла. Это необходимо сделать в BASH, используя SED/AWK. Нет, пожалуйста.Самый простой способ извлечь URL-адреса с html-страницы только с помощью sed или awk

Что такое самый простой способ сделать это?

+9

Прочтите это и просветите: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 –

+0

Если вы не против, чтобы : * Нет никакой гарантии, что вы найдете все URL-адреса. * ** или ** * Нет гарантии, что все найденные вами URL-адреса действительны. * Используйте один из приведенных ниже примеров. Если вы решите использовать подходящий инструмент для задания (perl, python, ruby) – Nifle

+0

Мой предыдущий комментарий - это конечно для любого * легкого * решения, которое вы можете попробовать. awk достаточно силен, чтобы выполнять эту работу, черт возьми, вы могли бы теоретически реализовать perl в awk ... – Nifle

ответ

10

пример, так как вы не предоставили какой-либо образец

awk 'BEGIN{ 
RS="</a>" 
IGNORECASE=1 
} 
{ 
    for(o=1;o<=NF;o++){ 
    if ($o ~ /href/){ 
     gsub(/.*href=\042/,"",$o) 
     gsub(/\042.*/,"",$o) 
     print $(o) 
    } 
    } 
}' index.html 
+0

Работает ли это для 'SELFHTML aktuell' –

+0

, если я говорю, что это работает (может быть, не 100%, но 99,99%) того времени, вы бы поверили ?? :). Лучше всего попробовать себя на разных страницах и посмотреть. – ghostdog74

+1

это действительно сделало работу, многие большие спасибо за этот большой комплект awk! – SomniusX

5

Вы можете сделать это довольно легко с помощью следующего регулярного выражения, которое довольно хорошо находящих URL-адресов:

\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))) 

я взял это от John Gruber's article on how to find URLs in text.

Это позволяет найти все URL-адреса в файле f.html следующим образом:

cat f.html | grep -o \ 
    -E '\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))' 
+1

сложный и не удается, когда href выглядит так: ... HREF = "http://www.somewhere.com/" ADD_DATE = "1197958879" LAST_MODIFIED = "1249591429"> ... – ghostdog74

+0

Я пробовал его на странице daringfireball и он нашел все ссылки. другие решения могут выйти из строя, потому что href = может быть где-то внутри обычного текста. трудно понять это абсолютно правильно, не анализируя HTML в соответствии с его грамматикой. – nes1983

+2

Вам не нужно иметь кошку перед grep. Просто поместите f.html в конец grep – monksy

4

Я предполагаю, что вы хотите, чтобы извлечь URL из некоторого HTML текста, а не анализировать HTML (как один из комментариев предлагает). Верьте или нет, у кого-то уже есть done this.

OT: sed website имеет лот полезной информации и многих интересных/сумасшедших сценариев. Вы можете даже playSokoban в sed!

+0

Это самый простой и простой ответ. Просто сделайте, например. 'wget http://sed.sourceforge.net/grabbag/scripts/list_urls.sed -O ~/bin/list_urls.sed && chmod + x ~/bin/list_urls.sed', чтобы получить скрипт, а затем' wget http : //www.example.com -O - | ~/bin/list_urls.sed> example.com.urls.txt', чтобы получить URL-адреса в текстовом файле! – arjan

32

Вы просили об этом:

$ wget -O - http://stackoverflow.com | \ 
    grep -o '<a href=['"'"'"][^"'"'"']*['"'"'"]' | \ 
    sed -e 's/^<a href=["'"'"']//' -e 's/["'"'"']$//' 

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

+1

Почти идеальный, но что об этом два случая: 1. Вы сравниваться только те, которые начинаются с Match me 2. Что делать, если есть два якоря в одной и той же линии Я сделал это изменения в исходном растворе: ' code' cat index.html | grep -o '' | sed -e 's/ Crisboot

+0

awesome! Спасибо! –

49

Вы также можете сделать что-то вроде этого (при условии, вы установили рысь) ...

Lynx версии < 2.8.8

lynx -dump -listonly my.html 

Lynx версии> = 2.8.8 (любезно @condit)

lynx -dump -hiddenlinks=listonly my.html 
+2

В Lynx 2.8.8 это стало 'lynx -dump -hiddenlinks = listonly my.html' – condit

8

Я сделал несколько изменений в Greg Bacon Solution

cat index.html | grep -o '<a .*href=.*>' | sed -e 's/<a /\n<a /g' | sed -e 's/<a .*href=['"'"'"]//' -e 's/["'"'"'].*$//' -e '/^$/ d' 

Это исправляет две проблемы:

  1. Мы соответствующие случаи, когда якорь не начинается с HREF в качестве первого атрибута
  2. Мы охватываем возможность иметь несколько якорей в одной и той же линии
+0

Но, по крайней мере, это решает проблему, ни одно из других решений не делает – Crisboot

+1

. Лучший вариант здесь, если вы не хотите использовать Lynx и ваши якоря не начинаются с simon

13
grep "<a href=" sourcepage.html 
    |sed "s/<a href/\\n<a href/g" 
    |sed 's/\"/\"><\/a>\n/2' 
    |grep href 
    |sort |uniq 
  1. Первый grep ищет строки, содержащие URL-адреса. Вы можете добавить больше элементов после того, как вы хотите посмотреть только на местных страницах, поэтому нет http, но относительный путь.
  2. Первая СЭД добавит новую строку перед каждой A HREF URL-адрес тега с \ п
  3. Второй СЭД сократит каждый URL после второго "в строке, заменив его на тег с новой строки Оба SEDs даст вам каждый URL на одной строке, но есть мусор, так
  4. 2-я Grep HREF очищает беспорядок
  5. рода и уник даст вам один экземпляр каждого существующего URL присутствуют в источнике.html
+1

Приятно сломать то, что каждый шаг должен сделать. –

0

Вы можете попробовать:

curl --silent -u "<username>:<password>" http://<NAGIOS_HOST/nagios/cgi-bin/status.cgi|grep 'extinfo.cgi?type=1&host='|grep "status"|awk -F'</A>' '{print $1}'|awk -F"'>" '{print $3"\t"$1}'|sed 's/<\/a>&nbsp;<\/td>//g'| column -c2 -t|awk '{print $1}' 
+0

Пожалуйста, отформатируйте свой код! – poplitea

13

С Xidel - HTML/XML data extraction tool, это может быть сделано с помощью:

$ xidel --extract "//a/@href" http://example.com/ 

С преобразованием в абсолютные адреса:

$ xidel --extract "//a/resolve-uri(@href, base-uri())" http://example.com/ 
+0

concat ожидает 2 аргумента, но здесь только один (базовый url задан). ERR: XPST0017: неизвестная функция: CONCAT # 1 вы имели в виду: В модуле http://www.w3.org/2005/xpath-functions: CONCAT # 2-65535 – smihael

+0

@smihael: Вы правы , это лишнее. Удалили. Спасибо, что заметили! –

1

Подойдите с первым проходом заменив начало URL (http) на новую строку (\n http). Тогда вы сами убедитесь, что ваша ссылка начинается в начале строки и является единственным URL-адресом на линии.

Остальное должно быть легко, вот пример:

sed "s/http/\nhttp/g" <(curl "http://www.cnn.com") | sed -n "s/\(^http[s]*:[a-Z0-9/.=?_-]*\)\(.*\)/\1/p"

alias lsurls='_(){ sed "s/http/\nhttp/g" "${1}" | sed -n "s/\(^http[s]*:[a-Z0-9/.=?_-]*\)\(.*\)/\1/p"; }; _'

1

Расширяя kerkael's answer:

grep "<a href=" sourcepage.html 
    |sed "s/<a href/\\n<a href/g" 
    |sed 's/\"/\"><\/a>\n/2' 
    |grep href 
    |sort |uniq 
# now adding some more 
    |grep -v "<a href=\"#" 
    |grep -v "<a href=\"../" 
    |grep -v "<a href=\"http" 

Первый Grep я добавил удаляет ссылки на локальные закладки.

Второй удаляет относительные ссылки на верхние уровни.

Третий удаляет ссылки, которые не начинаются с http.

Выберите, какой из них вы используете в соответствии с вашими конкретными требованиями.

0

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

a=$1 

lynx -listonly -dump "$a" > temp 

awk 'FNR > 2 {print$2}' temp > temp2.txt 

rm temp 

>sh test.sh http://link.com 
+0

Я настоятельно рекомендую использовать конвейер вместо временных файлов: lynx -listonly -dump "$ url" | awk 'FNR> 2 {print $ 2}' –

0

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

  1. С первых 7 большинством голосовавших ответов, 4 включают GREP, даже когда в post явно говорит «использование только sed или awk».
  2. Даже если сообщение требует «Нет perl please», из-за предыдущей точки и потому, что используйте регулярное выражение PERL внутри grep.
  3. и потому, что это самый простой способ (насколько я знаю, и это было ), чтобы сделать это в BASH.

Итак, вот самый простой скрипт из GNU grep 2.28:

grep -Po 'href="\K.*?(?=")' 

О переключателе \K, не информация была основана в МАН и INFO страниц, поэтому я пришел here за ответ .... переключатель \K изжить предыдущие символы (и сам ключ) , Имейте в виду, следуя советам на страницах руководства: «Это очень экспериментально, и grep -P может предупреждать о нереализованных функциях».

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

Я надеюсь, что люди вы это очень полезно.

спасибо !!!

 Смежные вопросы

  • Нет связанных вопросов^_^