Соскоб с экрана через нокогири или hpricot - PullRequest
0 голосов
/ 17 октября 2011

Я пытаюсь получить фактическое значение заданного xpath.У меня есть следующий код в файле sample.rb

require 'rubygems'
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::HTML(open('http://www.changebadtogood.com/'))
desc "Trying to get the value of given xapth"
task :sample do
  begin
    doc.xpath('//*[@id="view_more"]').each do |link|
      puts link.content
    end
  rescue Exception => e
    puts "error" 
  end
end

Вывод:

Просмотреть больше вопросов ..

Когда я пытаюсь получить значение для другого другого XPath, например:
/html/body/div[4]/div[3]/h1/span, тогда я получаю сообщение "error" .

Я пытался в этом вNokogiri.Я не знаю, почему это дает результат только для нескольких XPath.

Я попробовал то же самое в Hpricot.
http://hpricot.com/demonstrations

Я вставляю свои URL и XPath и вижурезультат для
//*[@id="view_more"]
как
Просмотреть больше проблем ..
[Этот текст присутствует внизу заголовка последних проблем]

Но он не показывает результат для:
/html/body/div[4]/div[3]/h1/span Для этого XPath я ожидаю результат Bad.
[Это было в http://www.changebadtogood.com/в качестве первого заголовка class = "hero-unit" div.]

1 Ответ

2 голосов
/ 18 октября 2011

Ваша проблема связана с плохим селектором XPath и не связана с Nokogiri или Hpricot.Давайте исследуем:

irb:01:0> require 'nokogiri'; require 'open-uri'
#=> true
irb:02:0> doc = Nokogiri::HTML(open('http://www.changebadtogood.com/')); nil
#=> nil
irb:03:0> doc.xpath('//*[@id="view_more"]').each{ |link| puts link.content }
View more issues ..
#=> 0
irb:04:0> doc.at('#view_more').text  # Simpler version of the above.
#=> "View more issues .."
irb:05:0> doc.xpath('/html/body/div[4]/div[3]/h1/span')
#=> []
irb:06:0> doc.xpath('/html/body/div[4]')
#=> []
irb:07:0> doc.xpath('/html/body/div').length
#=> 2

Из этого мы можем видеть, что есть только два div, которые являются дочерними элементами элемента <body>, и поэтому div[4] не может выбрать один.

ItПохоже, вы пытаетесь выбрать диапазон здесь:

<h1 class="landing_page_title">
  Change <span style='color: #808080;'>Bad</span> To Good
</h1>

Вместо того, чтобы полагаться на хрупкую разметку, ведущую к этому (индексация анонимных иерархий элементов), используйте семантическую структуру документа в ваших интересахдля селектора, который является одновременно более простым и надежным.Использование синтаксиса CSS или XPath:

irb:08:0> doc.at('h1.landing_page_title > span').text
#=> "Bad"
irb:09:0> doc.at_xpath('//h1[@class="landing_page_title"]/span').text
#=> "Bad"
...