Nokogiri - разбор многострочного тега `<link>` в виде ссылки и текста - PullRequest
0 голосов
/ 22 мая 2018

Я использую Nokogiri для разбора RSS-канала для подкаста.Я пытаюсь получить определенный фрагмент данных, содержащий ссылку на эпизод, поэтому я использую Nokogiri для анализа XML-ответа для RSS-канала.

Соответствующий бит ниже:

<item>
  <title>An awesome title!</title>
  ...
  <link>
    http://www.foobar.com/episodes/1
  </link>
</item>

Нокогири, похоже, с трудом хватает тег <link>;Я могу получить тег <item> как объект Nokogiri::Node, и я могу просто получить заголовок с помощью node.css('title').text, но когда я пытаюсь сделать то же самое с node.css('link').text, я получаю пустую строку.

Я попытался вызвать node.children.to_a, чтобы проверить все дочерние элементы в этом узле, и заметил нечто странное: текст внутри тега <link> анализируется как отдельный дочерний элемент:

[0] = {Nokogiri::XML::Element} <title>An awesome title!</title>\n
[1] = {Nokogiri::XML::Element} <link>
[2] = {Nokogiri::XML::Text} http://www.foobar.com/episodes/1\n

Есть ли способ, которым я могу помочь Nokogiri правильно разобрать этот многострочный тег, чтобы я мог захватить текст внутри?

ОБНОВЛЕНИЕ: Вот точный код, который я выполняю при запускев вопросе.

require 'open-uri'
doc = Nokogiri::HTML(open('https://rss.acast.com/abroadinjapan')) # Returns Nokogiri::HTML::Document
node = doc.css('//item').first # Returns Nokogiri::XML::Element
node.css('title').text # Returns "Abroad in Japan: Two weeks more in Japan!"
node.css('link').text # Returns ""
node.css('link').inner_text # Also returns "" - saw this elsewhere and thought I'd try it
node.children.to_a # Result, parsed by RubyMine for readability:

result = Array (14 elements)
 [0] = {Nokogiri::XML::Element} <title>Abroad in Japan: Two weeks more in Japan!</title>\n
 [1] = {Nokogiri::XML::Element} <subtitle>Chris and Pete return and they've planned out a very different route through Northern Japan.&amp;nbsp;\n\n\nOur Google Map can be found here:&amp;nbsp;\ngoo.gl/3t4t3q&amp;nbsp;\n\n\nGet in touch:&amp;nbsp;abroadinjapanpodcast@gmail.com&amp;nbsp;\nMore Abr...</subtitle>
 [2] = {Nokogiri::XML::Element} <summary></summary>
 [3] = {Nokogiri::XML::Element} <guid ispermalink="false"></guid>
 [4] = {Nokogiri::XML::Element} <pubdate>Wed, 16 May 2018 21:00:00 GMT</pubdate>
 [5] = {Nokogiri::XML::Element} <duration>01:00:00</duration>
 [6] = {Nokogiri::XML::Element} <keywords></keywords>
 [7] = {Nokogiri::XML::Element} <explicit>no</explicit>
 [8] = {Nokogiri::XML::Element} <episodetype>full</episodetype>
 [9] = {Nokogiri::XML::Element} <image href="https://imagecdn.acast.com/image?h=1500&amp;w=1500&amp;source=https%3A%2F%2Fmediacdn.acast.com%2Fassets%2Fcb30d29f-7342-46f0-a649-12f1b4e601f7%2Fcover-image-jgyt2ecc-japan.jpg"></image>
 [10] = {Nokogiri::XML::Element} <description>Chris and Pete return and they've planned out a very different route through Northern Japan. <p><br></p>\n<p>Our Google Map can be found here: </p>\n<p><a href="https://foobar.com/zqWZss9GSF" target="_blank">goo.gl/3t4t3q </a></p>\n<p><br></p>\n<p>Get in touch: <a href="mailto:abroadinjapanpodcast@gmail.com" target="_blank">abroadinjapanpodcast@gmail.com</a> </p>\n<p>More Abroad In Japan shows available below, do subscribe, rate and review us on iTunes, and please tell your friends! </p>\n<p><br></p>\n<p><a href="http://www.radiostakhanov.com/abroadinjapan/" target="_blank">http://www.radiostakhanov.com/abroadinjapan/</a></p>]]&gt;</description>
 [11] = {Nokogiri::XML::Element} <link>
 [12] = {Nokogiri::XML::Text} https://www.acast.com/abroadinjapan/abroadinjapan-twoweeksmoreinjapan-\n                
 [13] = {Nokogiri::XML::Element} <enclosure url="https://media.acast.com/abroadinjapan/abroadinjapan-twoweeksmoreinjapan-/media.mp3" length="28806528" type="audio/mpeg"></enclosure>

ПРИМЕЧАНИЕ. В одном из приведенных выше URL-адресов используется сокращатель URL-адреса, который ТАК не нравится, поэтому я заменил его на foobar.com.

1 Ответ

0 голосов
/ 22 мая 2018

Исправление намного проще, чем вы думаете.Канал RSS не является допустимым HTML, но он работает с XML:

doc = Nokogiri::XML(open('...'))

В Ruby также есть модуль с именем RSS , который лучше подходит для чего-то подобного:

require 'rss'
doc = RSS::Parser.parse(open('...'))
doc.items.first.link
=> "https://...."
...