Ваш 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]"