使用Nokogiri库的无尽循环;无法弄清楚为什么

时间:2012-02-04 07:39:23

标签: ruby nokogiri

我试图从网页的各个部分提取文本并将它们推送到一个数组(每个网页一个索引。)以下代码永远循环,我无法弄清楚原因:

def pull_text(urls)
  results = []
  urls.each do |something|
    doc = Nokogiri::HTML(open(something))
    main_text = doc.xpath('//div[@class="modText"]').inner_text
    blue_text =  doc.xpath('//div[@class="Text color2"]').inner_text
    grey_text =  doc.xpath('//div[@class="Text color1"]').inner_text
    table_text = doc.xpath('//div[@class="Table color"]').inner_text
    all_text = main_text + blue_text + grey_text + table_text
    results << all_text
  end
end

我还注意到,当我没有将doc.xpath行分配给变量时,它将在没有永久循环的情况下运行,但我无法想象如何以其他方式将所有内容推送到数组中。

但是,我确实注意到,当我向该方法提供单个网址时,它可以正常工作。但是,我需要这种方法能够处理多个网址,而不仅仅是一个。

def grab_text(url)
  doc = Nokogiri::HTML(open(url))
  main_text = doc.xpath('//div[@class="modText"]').inner_text
  blue_text =  doc.xpath('//div[@class="Text color2"]').inner_text
  grey_text =  doc.xpath('//div[@class="Text color1"]').inner_text
  table_text = doc.xpath('//div[@class="Table color"]').inner_text
  all_text = main_text + blue_text + grey_text + table_text
end

对不起那么棒的设计感到抱歉。我生锈了,在编程方面仍然很新。 :S

2 个答案:

答案 0 :(得分:2)

@pguardiario,是对的。在Ruby方法中,隐式返回块的最后一行或返回值。因此,在您的情况下,您返回urls.each而不是results的返回值。

然而,话虽如此,这是使用Enumerable module编写它的更惯用的方式。

我在下面的代码段中使用了Enumerable中的以下方法 - injectmap

TEXT_XPATHS = [ '//div[@class="modText"]',
                '//div[@class="Text color2"]',
                '//div[@class="Text color1"]',
                '//div[@class="Table color"]' ]                  

# 
# extract_text_from( a_single_url )
#
# extract_text_from( ["a", "list", "of", "urls"] )
#
def extract_text_from(urls)
  Array(urls).inject([]) do |results, url|
    html = Nokogiri::HTML( open(url) )

    texts = TEXT_XPATHS.map { |xpath| html.xpath(xpath).inner_text }

    results << texts.join
  end
end

答案 1 :(得分:2)

模式空数组+每个+推送+返回数组(代码中缺少最后一个东西) - &gt; map(更多关于Ruby here的函数式编程)

def pull_text(urls)
  urls.map do |url|
    doc = Nokogiri::HTML(open(url))
    main_text = doc.xpath('//div[@class="modText"]').inner_text
    blue_text =  doc.xpath('//div[@class="Text color2"]').inner_text
    grey_text =  doc.xpath('//div[@class="Text color1"]').inner_text
    table_text = doc.xpath('//div[@class="Table color"]').inner_text
    main_text + blue_text + grey_text + table_text
  end
end

提取常见模式:

def pull_text(urls)
  urls.map do |url|
    doc = Nokogiri::HTML(open(url))
    ["modText", "Text color2", "Text color1", "Table color"].map do |klass|
      doc.xpath("//div[@class='#{klass}']").inner_text
    end.join
  end
end