如何通过 Nokogiri 在页面上获取特定的可查看字符串

How to get a specific viewable string on page through Nokogiri

提问人:Dtrav 提问时间:5/15/2020 最后编辑:the Tin ManDtrav 更新时间:5/16/2020 访问量:68

问:

目前,我能够使用 Nokogiri 解析网站并从页面中获取特定元素。但是,我需要能够抓取用户可见的特定字符串,例如“缺货”:

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

我也知道我可以抓取包含字符串的特定标签,但我需要监控数百个网站,因此解决方案必须是广泛搜索可见字符串。

Ruby Capybara HTML-解析 Nokogiri

评论

2赞 Les Nightingill 5/16/2020
页面抓取是出了名的不可靠,尤其是当您试图让它在数百个网站上工作时。首先,您可以尝试包含前面和后面字符的正则表达式搜索。但是,尽管它可能会有所帮助,但这绝不是万无一失的。我也会看看水豚......它可能不是特别高性能,但可能会更可靠。><
1赞 Siim Liiser 5/16/2020
此外,“可见”有时很难指定。如果它在脚本中,它显然是不可见的。如果它有 style=“display: none”,那么它也可能不可见。但是,如果它是白色背景上的白色怎么办。如果它在别的东西后面怎么办,如果它被放置在页面之外怎么办,如果它的字体大小是微观的怎么办?
1赞 the Tin Man 5/16/2020
你必须做一些比搜索短文本字符串更具体、更准确的事情;这太容易被愚弄了。当与数百个网站合作时,你很有可能不得不编写数百个蜘蛛,因为每个网站对页面的编码都不同。尽可能利用对其站点的 REST 或 API 调用,因为您获得的数据将更容易处理并且更可靠。
0赞 max 5/16/2020
如果没有 API,你真的应该问问自己,你所做的事情是否违反了 TOS。

答:

1赞 Alex Strizhak 5/16/2020 #1

简短的回答:我们可以更具体地使用语法。xpath

说来话长: 我强烈建议将 css 类更具体,因为在某些情况下,我们不仅可以在“脚本标签”中获取此文本,还可以通过媒体查询或项目预览块或其他方式获取此文本,并将常见情况作为大块处理,但不要强制对所有情况使用一个特定的解决方案,以防出现意外行为

因此,我们需要更具体,并使用“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

我希望对您有所帮助

评论

0赞 the Tin Man 5/16/2020
如果网站使用 CSS 或 DHTML 以编程方式隐藏或显示“缺货”字符串,则此操作效果不佳。Nokogiri 不知道页面的状态,它只知道标记包含的内容。在命令行中用于加载页面并在 DOM 中查看;它仅适用于静态页面。nokogiri
0赞 Dtrav 5/19/2020
非常好。下面这个例子非常有效。非常感谢!