使用 Swift Soup 从任何网站获取产品价格

Posted

技术标签:

【中文标题】使用 Swift Soup 从任何网站获取产品价格【英文标题】:Scrape product price from any Website using Swift Soup 【发布时间】:2020-04-19 20:31:12 【问题描述】:

在我的应用程序中,我想获取任何产品的价格(用户输入想要的 URL)。

我现在搜索了很多,发现有几个Webscrapers,我想我现在会使用SwiftSoup。但是,我找不到一个教程来教如何 scrape 使用“动态”tags 的元素。例如,网站上产品的price 在每个网站上看起来都不同:

示例 1:

<div class="price">82 EUR</div>

示例 2:

<span class="gl-price__value">€ 139,95</span>

示例 3:

<span id="priceblock_ourprice" class="a-size-medium a-color-price priceBlockBuyingPriceString">79,99&nbsp;€</span>

我知道我可以scrape 像这样的元素:

let html: String = "<a id=1 href='?foo=bar&mid&lt=true'>One</a> <a id=2 href='?foo=bar&lt;qux&lg=1'>Two</a>";
let els: Elements = try SwiftSoup.parse(html).select("a");
for element: Element in els.array()
    print(try element.attr("href"))

但是动态scrape 的最佳方式是什么?在这方面找不到任何东西,所以我很高兴得到每一个帮助:)

更新

如果我知道确切的“类名”,我就能得到正确的“价格”:

let url = "https://www.adidas.de/adistar-trikot/CV7089.html"
    let className = "gl-price__value"


    do 
        let html: String = getHTMLfromURL(url: url)
        let doc: Document = try SwiftSoup.parse(html)

        let price: Element = try doc.getElementsByClass(className).first()!
        let priceText : String = try price.text()

        result.text = priceText

     catch Exception.Error(let type, let message) 
        print(message)
     catch 
        print("error")
    

但是,我想让这个工作,所以上面的所有 3 个例子都工作。现在我正在努力获得包含所有三个示例的正确“正则表达式”......任何想法?

【问题讨论】:

【参考方案1】:

我认为没有一种方法可以“动态地”抓取几乎任何东西。您无法检测到人们在向您显示价格时编写 html 的所有可能方式。

您可以做的,但我认为不会那么容易,就是训练一个机器学习模型来检测价格大部分时间。但这可能超出了这个问题的范围。

您可以尝试的另一种方法是简单地查看大多数网站并添加几个“通用”算法来抓取他们的网站。如果一个不起作用,你只需尝试另一个,直到你成功或放弃。这样,避免对类名和其他内容进行硬编码,您至少可以抓取所有与通用抓取工具中结构相似的网站。

一种方法(但我相信您可以想到其他更好的方法)我将实现“通用”刮板算法的方法是拥有价格类别的正则表达式列表以匹配并尝试使用它们全部,然后尝试验证您在 html 文本中得到的结果(例如,文本中是否有任何数字?它是否包含诸如 €、$、..?等符号)。 我会从 .*price.* 和其他类似的正则表达式开始,您可以通过查看大多数网站来轻松找到。

您肯定会在一些您没有想到的网站中遇到问题。然后您可以向自己发送该信息(当您在客户端上检测到您在网站上找不到价格时),您可以自己查看该网站并在您的列表中添加更多正则表达式(这可能需要更新服务器侧并在每次更新时下载到您的客户端上),如果这样可以解决问题,或者添加另一个刮板算法或使您以前的一个更通用并使用该用例(但这需要一个新的应用程序版本)。

如果这个答案不是很具体,我很抱歉,但你的问题太广泛了,几乎不可能更具体。

PS:不确定这是否是最好的方法(也许某些解析器更适合此方法),但我可以迅速想到一个正则表达式,它与您的所有 3 个示例匹配,其中 &lt;[^&gt;]*class=".*price.*"[^&gt;]*&gt;([^&lt;]*)&lt;。 可能有一些更聪明的东西,但是使用这个正则表达式,您将自动获取第一个捕获组中 html 元素内的文本。比你只需要清理它(删除不需要的字符等)并验证它。

【讨论】:

感谢您的回答!机器学习听起来很有趣,但超出了范围:D 以下是我在想如何解决这个问题:我需要一种方法来获取classes,特别是class names。然后我可以添加某种regex,这样我就可以像这样搜索:if class == matchRegex("price") return value 你知道我的意思吗?你能帮我解决这个问题吗? 我不明白你具体需要什么。无论如何,如果您只想要课程的正则表达式,那么这篇文章可以帮助您:***.com/questions/45759496/… 否则,如果您想知道如何快速使用正则表达式,请查看:hackingwithswift.com/articles/108/… 现在我正在努力完成“正则表达式”。您可能知道上面 3 个示例的正确“正则表达式”吗??? 谢谢!我得到了它与上面的三个例子一起工作。你似乎知道你的东西,你能看看这个问题吗? ***.com/questions/61432613/… 我想将所有与 price-regex 匹配的类放入一个数组中,这样我就可以通过它来获得我需要的类

以上是关于使用 Swift Soup 从任何网站获取产品价格的主要内容,如果未能解决你的问题,请参考以下文章

javascript 使用ASIN,从亚马逊产品广告API获取产品详细信息,然后打印价格

启用以使用 Beautiful Soup 获取特定网站的 img 标签

Swift IAP SK产品显示的价格错误

如何使用涉及html表的Beautiful Soup从页面中抓取产品信息[关闭]

爬虫---Beautiful Soup 爬取知乎热榜

从一个元素 JS 中获取产品价格