我正在尝试使用mechanize来解析网站的内容,而我却陷入困境。我要解析的内容位于li
标记内,但并不总是以相同的顺序排列。
让我们假设我们有以下内容,其中li
标签的顺序并不总是相同,有些甚至可能根本不存在。
<div class="details">
<ul>
<li><span>title 1</span> ": here are the details"</li>
<li><span>title 2</span> ": here are the details"</li>
<li><span>title 3</span> ": here are the details"</li>
<li><span>title 4</span> ": here are the details"</li>
</ul>
</div>
我想要的是仅获取li
文字所在的span
详细信息,例如title 3
。我所做的是以下内容,它为我提供了第一个li
:
puts page.at('.details').at('span', :text => "title 3").at("+ *").text
有没有办法用机械化做我想做的事情,还是我还应该用其他方法?
答案 0 :(得分:18)
page.search(".details").at("span:contains('title 3')").parent.text
说明: 使用 at ,您可以使用css或xpath选择器。为了使您的方法更具可读性和类似性,此答案使用css选择器,但问题是CSS无法基于文本执行选择。感谢Nokogiri,您可以使用JQuery选择器,因此允许包含方法。
选择获取span元素,因此如果要获取li元素parent,可以使用 parent 方法,然后轻松获取文本。
答案 1 :(得分:2)
由于您希望使用Mechanize(我看到其中一条评论建议使用Nokogiri),您应该知道Mechanize是建立在Nokogiri上的,因此您实际上可以使用任何/所有Nokogiri功能通过Mechanize。
通过http://mechanize.rubyforge.org/Mechanize.html
上的文档向您展示Mechanize.html_parser = Nokogiri :: XML
所以你可以使用XPath和mechanize page.search方法完成这个。
page.search(“// div [@ class ='details'] / ul / li [span ='title 3']”)。text
这应该能够为您提供您正在寻找的li元素的文本。 (未经验证.text,但XPath确实有效)
您可以在此处测试XPath:http://www.xpathtester.com/saved/51c5142c-dbef-4206-8fbc-1ba567373fb2
答案 2 :(得分:1)
清洁css
方法:
page.at('.details li:has(span[text()="title 3"])')
答案 3 :(得分:0)
根据评论,我认为你正在寻找类似下面的内容。
正如我所说的那样,问题在于它给了我第一个li而我想要的那个有文本标题3
require 'nokogiri'
doc = Nokogiri::HTML.parse <<-eotl
<div class="details">
<ul>
<li><span>title 1</span> ": here are the details"</li>
<li><span>title 2</span> ": here are the details"</li>
<li><span>title 3</span> ": here are the details"</li>
<li><span>title 4</span> ": here are the details"</li>
</ul>
</div>
eotl
node = doc.at_xpath("//div[@class='details']//span[contains(.,'title 3')]/..")
node.name # => "li"
puts node.to_html
# <li>
# <span>title 3</span> ": here are the details"</li>
puts node.children
#<span>title 3</span>
# ": here are the details"