如何通过 Nokogiri 在页面上获取特定的可查看字符串
Posted
技术标签:
【中文标题】如何通过 Nokogiri 在页面上获取特定的可查看字符串【英文标题】:How to get a specific viewable string on page through Nokogiri 【发布时间】:2020-09-01 10:55:30 【问题描述】:目前,我能够使用 Nokogiri 解析网站并从页面中获取特定元素。但是,我需要能够获取用户可见的特定字符串,例如“Out of stock”:
page.text.match('Out of stock')
这对于获取正确的字符串并在字符串存在或不存在时返回 true 或 false 非常有效,但是,如下所示的某些链接即使项目没有缺货也会返回 true,因为该特定字符串是隐藏在页面上的脚本标签中:
https://www.walmart.com/ip/Funyuns-Onion-Flavored-Rings-6-oz/36915849?athcpid=36915849&athpgid=athenaItemPage&athcgid=null&athznid=PWSFM&athieid=v0&athstid=CS020&athguid=ba634528-888-172187cc96a580&athancid=null&athena=true
我正在寻找一种方法,以便当且仅当它对用户可见时才会拉出该字符串,因此上面应该返回 false 以匹配“缺货”字符串,而下面的链接应该返回 true(有时发布),因为该项目实际上是缺货。
https://www.walmart.com/ip/4-Pack-Chesters-Flamin-Hot-Popcorn-4-25-oz/737202470?selected=true
我也知道我可以获取包含字符串的特定标签,但我需要监控数百个网站,因此解决方案必须是广泛搜索可见字符串。
【问题讨论】:
页面抓取是出了名的不可靠,尤其是当你试图让它在数百个网站上运行时。作为开始,您可以尝试包含前面的>
和后面的 <
字符的正则表达式搜索。但是,虽然它可能会有所帮助,但这绝不是万无一失的。我也会看看 Capybara ......它可能不是特别性能,但它可能会更可靠。
“可见”有时也很难指定。如果它在脚本中,它显然是不可见的。如果它有 style="display: none",那么它也可能不可见。但是,如果它是白色背景上的白色怎么办。如果它在其他东西后面怎么办,如果它位于页面之外怎么办,如果它的字体大小是微观的怎么办?
您必须做一些比搜索短文本字符串更具体和准确的事情;太容易上当了。当与数百个站点一起工作时,很有可能您必须编写数百个爬虫,因为每个站点对页面的代码都不同。尽可能利用对其站点的 REST 或 API 调用,因为您获得的数据将更容易处理且更可靠。
如果没有 API,你真的应该问问自己,你所做的是否违反了 TOS。
【参考方案1】:
简短的回答:我们可以使用更具体的xpath
语法。
长篇大论: 我强烈建议更具体地使用 css-classes,因为在某些情况下,我们不仅可以在“脚本标签”中获取此文本,还可以通过媒体查询或项目预览块或其他方式获取此文本,并将常见情况处理为大块,但不要强制在所有情况下都使用一种特定的解决方案,以防出现意外行为
所以我们需要更具体一些,使用“target-tags”来处理,例如:
Nokogiri::html.parse(page.html).xpath("//*[contains(@class, 'prod-PriceSection')]//*[contains(@class, 'prod-ProductOffer-oosMsg')]").text
"Out of stock"
所以,“监控数百个网站”我们可以采用这种方法:
xpath("//*[contains(@class, 'PriceSection')]").text
或者甚至更好地使用这样的东西来确保元素清晰可见:
page.all("//body//*[contains(text(), 'Out of stock')]", visible: true).count
# => 1
如果 Capybara 使用更多请求(在以前的解决方案中)可能会成为问题,我们可以使用此解决方案,它会更快:
xpath("//body//*[not(self::script) and contains(text(), 'Out of stock')]").count
希望对你有帮助
【讨论】:
如果网站使用 CSS 或 DHTML 以编程方式隐藏或显示“缺货”字符串,这将无法正常工作。 Nokogiri 不知道页面的状态,它只知道标记包含的内容。在命令行使用nokogiri
加载页面并查看DOM;它只适用于静态页面。
优秀。那个底部的例子效果很好。非常感谢!以上是关于如何通过 Nokogiri 在页面上获取特定的可查看字符串的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Nokogiri 获取没有任何文本内容的完整 HTML
如何在 Mac OS Sierra 10.12 上安装 Nokogiri
无法在 Ruby 版本高于要求的 CentOS 上安装 Nokogiri
使用Savon和Nokogiri在Rails中解析XML SOAP响应的内存不足