Вы не предоставили нам пример HTML, показывающий разметку, с которой вы работаете. Из-за этого вам очень трудно помочь. Не делай этого; Помогите нам помочь вам.
Mechanize использует Nokogiri для внутренних целей и может вернуть вам документ Nokogiri, так что вам нужно его получить. Оттуда вы попадаете во владения Нокогири, что дает вам больше контроля над поиском.
Использование Mechanize links_with
находит все соответствующие ссылки в документе и возвращает их в виде массива Node, также известного как NodeSet. Они, вероятно, содержат много других узлов внутри них, которые отвечают за вкладки и возвращаемые значения, которые вы видите. Хотя links_with
полезен, вы всегда должны знать, что что-то возвращает вам, чтобы вы могли правильно на это реагировать.
Проблема, которую вы видите, заключается в том, что вы не обращаетесь к правильному тегу при извлечении текста, или значения, которые вы говорите, что видите в ссылках, не совсем то, что вы сообщаете.
Учти это:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<p>foo</p>
|
<p>bar</p>
</body>
</html>
EOT
Извлечение текста из более высокого тега (родительского), чем тот, который вы должны, вернет все в этом родительском:
doc.search('body').text # => "\nfoo\n|\nbar\n"
Обратите внимание, что он улавливает разрывы строк и |
между тегами. Это связано с тем, что text
возвращает все текстовые узлы, а не только те, что находятся внутри дочернего тега. Поэтому очень важно четко указать, чего вы хотите.
Точно так же поиск только тегов p
возвращает весь текст, найденный внутри них:
doc.search('p').text # => "foobar"
Это также обычно не работает, так как text
объединяет весь текст в узлах, найденных в NodeSet, возвращаемом search
, что обычно не очень полезно.
Вместо этого найдите нужный узел и получите его текст:
doc.at('p').text # => "foo"
at
возвращает первый соответствующий узел и эквивалентен search('p').first
.
Если вам нужен весь текст из узлов p
, выполните итерацию по ним:
doc.search('p').map(&:text) # => ["foo", "bar"]
В более сложных документах нам часто приходится находить определенный ориентир в иерархии тегов и переходить к нему, а затем искать дальше, но это отдельная проблема.
Собрав все это вместе, вот пример, который помогает визуализировать то, с чем вы сталкиваетесь, и как с этим бороться:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<a href="http://example.com">
<span class="hubbub">foo</span>
</a>
|
<a href="http://example.com">
<span class="hubbub">bar</span>
</a>
</body>
</html>
EOT
Не делайте этого:
doc.search('body').text # => "\n \n foo\n \n |\n \n bar\n \n"
doc.search('a').text # => "\n foo\n \n bar\n "
Сделай это:
doc.search('a span').map(&:text) # => ["foo", "bar"]
Or:
spans = doc.search('a').map{ |link|
link.at('span').text
}
spans # => ["foo", "bar"]
Первый способ быстрее, потому что он использует код libXML2 для поиска соответствующих узлов span
, определенных в селекторе CSS 'a span'
. Второй медленнее, но более гибкий и позволяет вам использовать язык Ruby для итерации и просмотра тегов.
См. «Как избежать объединения всего текста с узлов при очистке." также.
person
the Tin Man
schedule
15.07.2015
regex
я с этим справляюсь. - person JonB   schedule 11.06.2015