hpricot генерирует исключение при попытке проанализировать URL, который имеет тег noscript - PullRequest
0 голосов
/ 08 апреля 2010

Я использую hpricot gem в ruby ​​on rails для анализа веб-страницы и извлечения содержимого мета-тега. Но если на сайте есть тег <noscrpit> сразу после тега <head>, он выдает исключение

Exception: undefined method `[]' for nil:NilClass

Я даже пытался обновить гем до последней версии. но все тот же.

это пример кода, который я использую.

require 'rubygems'
require 'hpricot'
require 'open-uri'
begin
       index_page = Hpricot(open("http://sample.com"))
       puts index_page.at("/html/head/meta[@name='verification']")['content'].gsub(/\s/, "")
rescue Exception => e
       puts "Exception: #{e}"
end

Я думал удалить тег noscript перед тем, как передать веб-страницу hpricot. или есть другой способ сделать это?

мой фрагмент HTML

<html> 
<head> 
<noscript> 
<meta http-equiv="refresh" content="0; url=http://www.yoursite.com/noscripts.html"/> 
</noscript> 
<meta name="verification" content="7ff5e90iormq5niy6x98j75-o1yqwcds-c1b1pjpdxt3ngypzdg7p80d6l6xnz5v3buldmmjcd4hsoyagyh4w95-ushorff60-f2e9bzgwuzg4qarx4z8xkmefbe-0-f" /> 
</head> 
<body> 
<h1>Testing</h1> 
</body> 
</html>

1 Ответ

0 голосов
/ 11 апреля 2010

Я не могу продублировать исключение с Hpricot.Тем не менее, я вижу проблемы с тем, как вы пытаетесь найти метатег.

Я сократил образец HTML, чтобы мой пример кода поместился здесь, в поле ответа, затем сохранил HTML локально, чтобы я мог использовать open-uri, чтобы добраться до него.

<html> 
<head> 
<noscript> 
<meta http-equiv="refresh" /> 
</noscript> 
<meta name="norton-safeweb-site-verification" /> 
</head> 
<body> 
<h1>Testing</h1> 
</body> 
</html>

Размышляйте о результатах поиска ниже:

#!/usr/bin/env ruby

require &#x27;rubygems&#x27;
require &#x27;hpricot&#x27;
require &#x27;open-uri&#x27;

doc = Hpricot(open(&#x27;http://localhost:3000/test.html&#x27;))

(doc / &#x27;meta&#x27;).size # => 2
(doc / &#x27;meta&#x27;)[1] # => {emptyelem <meta name="norton-safeweb-site-verification">}

(doc % &#x27;meta[@name]&#x27;) # => {emptyelem <meta name="norton-safeweb-site-verification">}

(doc % &#x27;meta[@name="verification"]&#x27;) # => nil
(doc % &#x27;meta[@name*="verification"]&#x27;) # => {emptyelem <meta name="norton-safeweb-site-verification">}

(doc % &#x27;meta[@name="norton-safeweb-site-verification"]&#x27;) # => {emptyelem <meta name="norton-safeweb-site-verification">}

Помните, что '/' в Hpricot означает .search () или "найти все вхождения"и"% "означает .at () или" найти первое вхождение ".Использование длинного пути, чтобы добраться до нужного элемента, часто менее вероятно, чтобы найти то, что вы хотите.Ищите уникальные вещи в элементе или его родных братьях или родителях.Длинный аксессор ломается легче, потому что предыдущий макет страницы учитывается при поиске;Если что-то на странице изменится, средство доступа будет недействительным, поэтому ищите атомарно или в наименьшей группе элементов, которую вы можете.Кроме того, документы Hpricot рекомендуют использовать средства доступа CSS, поэтому я использую их в примере кода.

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

Поиск «мета с параметром имени» нашел цель.

Поиск «мета с параметром имени, состоящим из 'проверка не проходит, потому что ее нет.Поиск внутри параметра с использованием «* =» работает.

Поиск «мета с параметром имени, состоящим из« norton-safeweb-site-validation »» успешен, поскольку это полное значение параметра.

Hpricot имеет довольно хороший набор CSS-селекторов:

http://wiki.github.com/whymirror/hpricot/supported-css-selectors

Теперь, все, что сказано, I рекомендует использовать Nokogiri вместо Hpricot.Я обнаружил случаи, когда Hpricot молчаливо терпел неудачу, но Nokogiri успешно анализировал искаженные XML и HTML.

...