Hpricot поиск, как - PullRequest
       44

Hpricot поиск, как

0 голосов
/ 03 декабря 2010

Я хотел бы выполнить поиск по веб-странице, если у меня есть результат, чем мне нужна недвижимость. Вот веб-страница: текст ссылки

Мне интересно, есть ли в заголовке мета свойство со значением "og: title" или нет, если я хочу содержимое значение

Если мы посмотрим на источник страницы, у него есть зелье:

<meta
property="og:title" content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" />

поэтому я хочу получить истинный результат для запроса og: title и значение Explore the Titanic Wreck Site with Social Media [EXCLUSIVE] для следующего поиска, как это сделать правильно

search("/html/head/meta[(@property='og:title']") не возвращает то, что я хочу.

есть предложения?

Ответы [ 3 ]

2 голосов
/ 03 декабря 2010

Использование:

/html/head/meta[@property='og:title']/@content
1 голос
/ 06 декабря 2010

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

Правильный поиск

elements = @doc.search("/html/head/meta[@property='og:title']")
  • удаляется символ ( из выражения перед @ property

Это дает:

elements = <meta property="og:title" content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" />

результат. Чем я проверяю, есть ли у меня что-то или нет, если мне нужно, то мне нужно значение контента

if elements.nil?
   puts 'not found'
  elsif elements.size > 0
    puts "Found one, og:title = #{elements}" 
    content = elements.attr("content");
    puts content # this will display the content ( it will be processed)
  else
    ... can come here the flow control? - theoretically yes, but in practice?
  end
1 голос
/ 03 декабря 2010

Ваш XPath содержит ошибку, плюс слишком ограничительный:

search("/html/head/meta[(@property='og:title']")

должно быть:

search("/html/head/meta[@property='og:title']")

чтобы исправить ошибку. Я бы упростил это до:

search("//meta[@property='og:title']")

Кроме того, не совсем понятно, что вы хотите сделать. Вы хотите найти

<meta 
  property="og:title" 
  content="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]" 
 />

и извлечь параметр content? Или вы хотите найти тег, подтвердить, что он содержит тег свойства "og:title" и содержимое "Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]", а затем выполнить дальнейшую обработку?

Тем не менее, часто проще использовать средства доступа CSS вместо XPath. Я предпочитаю использовать Nokogiri, который имеет как XPath, так и CSS-селекторы; Я использую CSS ниже:

require 'nokogiri'
require 'open-uri'

doc = Nokogiri::HTML(open('http://mashable.com/2010/08/06/expedition-titanic'))
(doc % 'meta[property="og:title"]')
=> #<Nokogiri::XML::Element:0x8084ee48 name="meta" attributes=[#<Nokogiri::XML::Attr:0x8084ed58 name="property" value="og:title">, #<Nokogiri::XML::Attr:0x8084ed1c name="content" value="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]">]>

Nokogiri и Hpricot поддерживают сокращение / и % для search и at соответственно. «Поиск» возвращает массив всех совпадений, а «at» возвращает только первое совпадение. Итак, приведенный выше пример получает первый узел, использующий CSS, показывая, что это верный путь. Я не уверен, как использовать CSS для сопоставления двух параметров в одном теге, поэтому я пойду после всех <meta> тегов с property="og:title", а затем отфильтрую по параметру content=:

(doc / 'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] }
=> [#<Nokogiri::XML::Element:0x8084ee48 name="meta" attributes=[#<Nokogiri::XML::Attr:0x8084ed58 name="property" value="og:title">, #<Nokogiri::XML::Attr:0x8084ed1c name="content" value="Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]">]>]

В этот момент у нас есть верный узел в возвращаемом массиве, так что вы можете извлекать все, что захотите, или погрузиться в его дочерние элементы, а также захватывать и грабить. Для этого вам нужно будет использовать .first или [0], чтобы добраться до фактического узла для дальнейшей обработки:

(doc / 'meta[property="og:title"]').select{ |n| n['content'][/titanic wreck site/i] }.first

Обновление, основанное на ответе ОП, с использованием Nokogiri:

>> meta = (doc % 'meta[@property="og:title"]')['content']
>> meta #=> "Explore the Titanic Wreck Site via Social Media [EXCLUSIVE]"
...