Я пытаюсь использовать Hpricot, чтобы получить значение в диапазоне с именем класса, которое я не знаю. Я знаю, что это следует шаблону "foo_ [несколько цифр] _bar".
Прямо сейчас я получаю весь содержащий элемент в виде строки и использую регулярное выражение для анализа строки для тега. Это решение работает, но кажется ужасным.
doc = Hpricot(open("http://scrape.example.com/search?q=#{ticker_symbol}"))
elements = doc.search("//span[@class='pr']").inner_html
string = ""
elements.each do |attr|
if(attr =~ /foo_\d+_bar/)
string = attr
end
end
# get rid of the span tags, just get the value
string.sub!(/<\/span>/, "")
string.sub!(/<span.+>/, "")
return string
Похоже, должен быть лучший способ сделать это. Я бы хотел сделать что-то вроде:
elements = doc.search("//span[@class='" + /foo_\d+_bar/ + "']").inner_html
Но это не работает. Есть ли способ поиска с помощью регулярного выражения?
3 ответа
Это должно делать:
doc.search("span[@class^='foo'][@class$='bar']")
Это должно делать:
doc.search("span[@class^='foo'][@class$='bar']")
В дополнение к этому мы можем привести еще несколько примеров того, как работают некоторые другие похожие выражения:
Для документа, подобного следующему:
Для каждого запроса мы получаем следующий результат:
doc.search("//meta[@content='abcxy def ghi jklmn']")
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>
Этого мы и ожидали.
doc.search("//meta[@content='def']")
=> #<Hpricot::Elements[]>
Как видите, = ищет точное совпадение.
doc.search("//meta[@content~='def']")
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>
С помощью ~ мы можем выполнить сопоставление подстроки; но не совсем то, чего вы ожидали.
Например, см. Следующее.
doc.search("//meta[@content~=' def ']")
=> #<Hpricot::Elements[]>
Кажется, что пробелы обрабатываются особым образом.
С помощью звезды мы можем решить эту проблему. Теперь мы выполняем истинное сопоставление подстрок.
doc.search("//meta[@content*=' def ']")
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>
Мы также можем выполнить сопоставление начала и конца строки следующим образом:
doc.search("//meta[@content^='def']")
=> #<Hpricot::Elements[]>
doc.search("//meta[@content^='ab']")
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>
doc.search("//meta[@content$='mn']")
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>
Учтите, что для этих пробелов не проблема.
doc.search("//meta[@content$=' jklmn']")
=> #<Hpricot::Elements[{emptyelem <meta content="abcxy def ghi jklmn">}]>
Можно изменить входящий html перед синтаксическим анализом.
html = open("http://scrape.example.com/search?q=#{ticker_symbol}").string
html.gsub!(/class="(foo_\d+_bar)"/){ |s| "class=\"foo_bar #{$1}\"" }
doc = Hpricot(html)
После этого вы можете идентифицировать элементы с помощью класса foo_bar
. Это далеко не изящно или универсально, но может оказаться более эффективным.
Похожие вопросы
Новые вопросы
ruby
Ruby - это многоплатформенный динамический объектно-ориентированный интерпретируемый язык с открытым исходным кодом. Тег [ruby] предназначен для вопросов, связанных с языком Ruby, включая его синтаксис и его библиотеки. Вопросы Ruby on Rails должны быть помечены [ruby-on-rails].