Как извлечь ссылки из HTML с помощью регулярных выражений? - PullRequest
1 голос
/ 08 февраля 2009

Я хочу извлечь ссылки с google.com; Мой HTML-код выглядит так:

<a href="http://www.test.com/" class="l"

Я потратил около пяти минут, чтобы найти регулярное выражение, работающее на www.rubular.com. Это:

"(.*?)" class="l"

Код:

require "open-uri"
url = "http://www.google.com/search?q=ruby"

source = open(url).read()
links = source.scan(/"(.*?)" class="l"/) 

links.each { |link| puts #{link} 
}

Проблема в том, что он не выводит ссылки на сайты.

Ответы [ 3 ]

4 голосов
/ 08 февраля 2009

Эти ссылки на самом деле имеют class=l, а не class="l". Кстати, чтобы понять это, я добавил в метод некоторую регистрацию, чтобы вы могли видеть результаты на разных этапах и отлаживать их. Я искал строку, которую вы ожидали найти, и не нашел ее, поэтому ваше регулярное выражение не удалось. Поэтому я искал правильную строку, которую вы на самом деле хотели, и соответственно изменил регулярное выражение. Навыки отладки удобны.

require "open-uri"
url = "http://www.google.com/search?q=ruby"

source = open(url).read

puts "--- PAGE SOURCE ---"
puts source

links = source.scan(/<a.+?href="(.+?)".+?class=l/)

puts "--- FOUND THIS MANY LINKS ---"
puts links.size

puts "--- PRINTING LINKS ---"
links.each do |link|
  puts "- #{link}"
end

Я также улучшил ваше регулярное выражение. Вы ищете некоторый текст, который начинается с открытия тега (<a), затем некоторые символы, которые вас не интересуют (.+?), атрибут href (href="), содержимое атрибут href, который вы хотите захватить ((.+?)), некоторые пробелы или другие атрибуты (.+?) и, наконец, атрибут attrubute класса (class=l).

У меня есть .+? в трех местах. . означает любой символ, + означает, что перед ним должна быть одна или несколько вещей, а ? означает, что .+ должен пытаться найти максимально короткую строку.

2 голосов
/ 08 февраля 2009

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

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

0 голосов
/ 08 февраля 2009

Что я не так делаю?

Вы пытаетесь проанализировать HTML с помощью регулярных выражений. Не делай этого. Регулярные выражения не могут охватывать диапазон синтаксиса, допустимый даже действительным XHTML, не говоря уже о реальном теговом супе. Используйте библиотеку HTML-анализатора, такую ​​как Hpricot.

FWIW, когда я получаю 100 http://www.google.com/search?q=ruby’, я не получаю ‘class =" l "’ нигде в возвращенной разметке. Возможно, это зависит от того, какой локальный Google вы используете и / или вошли ли вы в систему или иным образом имеете файлы cookie Google. (Ваш сценарий, как я, не будет.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...