Ruby 使用Nokogiri库的Neverening循环;can';我不明白为什么

Ruby 使用Nokogiri库的Neverening循环;can';我不明白为什么,ruby,nokogiri,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.xpat

我试图从网页的各个部分提取文本,并将它们推送到一个数组(每个网页一个索引)。下面的代码永远循环,我不明白为什么:

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

很抱歉,这个设计不太棒。我已经生疏了,编程还是个新手S是正确的。在Ruby方法中,隐式返回块的最后一行或返回值。因此,在您的示例中,您返回的是
URL的返回值。每个
而不是
结果

尽管如此,这里还是有一种更为惯用的方法来使用

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

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
TEXT\u XPATHS=['//div[@class=“modText”]',
“//div[@class=“Text color2”]”,
“//div[@class=“Text color1”]”,
'//div[@class=“Table color”]]
# 
#从(单个url)中提取文本
#
#从([“a”、“list”、“of”、“url”])中提取文本
#
def extract_text_from(URL)
数组(url)。注入([])do |结果,url|
html=Nokogiri::html(打开(url))
TEXT=TEXT_XPATHS.map{| xpath | html.xpath(xpath).inner_TEXT}

结果@pguardiario是正确的。在Ruby方法中,隐式返回块的最后一行或返回值。因此,在您的示例中,您返回的是
URL的返回值。每个
而不是
结果

尽管如此,这里还是有一种更为惯用的方法来使用

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

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
TEXT\u XPATHS=['//div[@class=“modText”]',
“//div[@class=“Text color2”]”,
“//div[@class=“Text color1”]”,
'//div[@class=“Table color”]]
# 
#从(单个url)中提取文本
#
#从([“a”、“list”、“of”、“url”])中提取文本
#
def extract_text_from(URL)
数组(url)。注入([])do |结果,url|
html=Nokogiri::html(打开(url))
TEXT=TEXT_XPATHS.map{| xpath | html.xpath(xpath).inner_TEXT}
结果模式空数组+each+push+return数组(代码中最后一个元素缺失)->
map
(更多关于Ruby函数编程的信息)

抽象常见模式:

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
模式空数组+each+push+return数组(代码中最后一个元素缺失)->
map
(更多关于Ruby函数编程的信息)

抽象常见模式:

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

我想你只是对返回值感到困惑。第一个方法可能会返回结果,对吗?它的编写方式将返回URL。如前所述,返回值存在问题,但我不明白为什么它会永远循环。你们试过调试它吗?请发布几个你们用来测试的URL。我想你们只是对返回值感到困惑。第一个方法可能会返回结果,对吗?它的编写方式将返回URL。如前所述,返回值存在问题,但我不明白为什么它会永远循环。你们试过调试它吗?请发布几个你们用来测试的URL。小心,你们在用inject模拟地图!和数组。reduce(:+)->array。join@tokland:
text.join
:-)。你能解释一下为什么在注入中使用map是一个问题,因为我没有在注入的数组上映射。我错过什么了吗?是的,抱歉,加入。另一件事:不,文本XPATHS.map没有问题,问题是您正在编写xs.inject([]){| output,x | output@tokland:您是对的,它们是等效的。顺便说一句,我的意思是我更新到
TEXT.join
而不是
TEXT.reduce(:+)
在您的评论之后:-)。干杯。小心,您正在使用inject!和array.reduce()模拟map->数组。join@tokland:
TEXT.join
:-)。你能解释一下为什么在inject中使用map是一个问题,因为我没有映射到注入的数组。我遗漏了什么吗?是的,对不起,TEXT.join。另一个问题是:不,TEXT\u XPATHS.map没有问题,问题是你正在编写xs.inject([]){| output,x | output@tokland:你是对的,它们是等价的。顺便说一句,我的意思是我更新到
文本。加入
而不是
文本。在你的评论之后减少(:+)
。干杯。