0

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

我现在搜索了很多,我发现有几个Webscrapers,我想我SwiftSoup现在会使用。但是,我找不到一个教程来教如何scrape使用 "dynamic" 获取元素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;€&lt;/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 个示例都有效。现在我正在努力获得包含所有三个示例的正确“正则表达式”......有人知道吗?

4

1 回答 1

1

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

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

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

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

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

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

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

于 2020-04-25T11:38:42.950 回答