2015-06-03 38 views
1

当我使用Mechanize links_with方法抓取一组链接时,我只想显示链接的文本,但我得到一系列额外字符:使用Ruby机械化“links_with”来抓取文本,但获取额外内容

links = @some_page.links_with(text: /V\s.*(BENCH|EARCX)|(BENCH|EARCX).*V/) 

links.each do |link| 
    link.text 
end 

的链接显示在浏览器中的“23409BENCH092834”和“20193BENCH092339”然而这正是我希望当我去将它们保存在我的数据库,他们得到保存为

\r\n\t\t\t\t\r\n\t\t\t\t\t 23409BENCH092834\r\n\t\t\t\t\r\n\t\t\t\t 

如果没有这些额外的角色来自他们代表什么?我试过对他们使用textto_s,但它并没有摆脱这些随机字符。


我认为他们可能是转义代码,但如果是的话,我会如何删除它们?

+1

使用'regex'是我处理这个问题的方式。 – JonB

回答

1

您没有给我们示例HTML,显示您正在使用的标记。这使你很难帮助你。不要那样做;帮助我们帮助你。

机械化使用Nokogiri内部并可以返回给你一个Nokogiri文件,所以你会想要得到它。从那里你在Nokogiri的领域,这将让你更多的控制搜索。

使用Mechanize的links_with查找文档中的所有匹配链接并将它们返回为Node,AKA 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平时工作将串联在返回的节点集发现的节点中的所有文本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"] 

或者:

spans = doc.search('a').map{ |link| 
    link.at('span').text 
} 
spans # => ["foo", "bar"] 

第一种速度更快,因为它依靠libXML2代码来查找'a span' CSS选择器中定义的匹配span节点。第二个比较慢,但更灵活,可以使用Ruby的语言迭代并查看标签。

也参见“How to avoid joining all text from Nodes when scraping”。