Erik

Join the chat at https://gitter.im/phimage/Erik License Platform Language Issues CocoapodCarthage compatible

Become a Patron! Buy me a coffee

Erik 是一个 无头浏览器,基于 WebKit 和 HTML 解析器 Kanna

无头浏览器允许运行功能测试,访问并使用 JavaScript 操作网页。

let browser = Erik.visit(url: url) { document, error in
    // browse HTML element, click, submit form and more
}

导航

跳转到 URL

Erik.visit(url: url) { object, error in
    if let e = error {

    } else if let doc = object {
        // HTML Inspection
    }
}

如何获取当前 URL?

if let url = Erik.currentURL {..}

对于多重浏览,您可以创建一个无头浏览器实例并使用相同的功能。

let browser = Erik()
browser.visitURL...

HTML 检查

通过 CSS 选择器搜索节点

for link in doc.querySelectorAll("a, link") {
    print(link.text)
    print(link["href"])
}

编辑名称为 "user" 的第一个输入字段

if let input = doc.querySelectorAll("input[name=\"user\"]").first {
    input["value"] = "Eric"
}

提交表单

if let form = doc.querySelector("form[id='search']") as? Form {
    form.submit()
}

执行一些 JavaScript 代码

let javaScriptSource = "console.log("test");"
Erik.evaluate(javaScript:javaScriptSource) { (obj, err) -> Void in
    if let error = err {
        switch error {
            case ErikError.javaScriptError(let message):
            print(message)
            default :
            print("\(error)")
        }
    }
    else if let capturedValue = obj {
        // do something according to result
    }
}

capturedValue 是 JavaScript 变量 resultErik 的内容。在您的 JavaScript 代码中影响此变量。

let javaScriptSource = "console.log('test'); var resultErik = 1 + 1;"

关于 DOM 更改的警告

⚠️所有对 DOM 的操作都使用 JavaScript,并且不会修改实际的 Document 对象及其子元素 Element

您必须使用 currentContent 来获取刷新的 Document 对象。

获取当前内容

Erik.currentContent { (obj, err) -> Void in
    if let error = err {
    }
    else if let document = obj {
       // HTML Inspection
    }
}

使用 Future

作为一个可选功能,您可以使用 Future/Promise (Erik 使用框架 BrightFutures & Result)。

提交 Google 搜索的示例

let url = NSURL(string:"https://www.google.com")!
let value = "Erik The Phantom of Opera"
// visit
var future: Future<Document, NSError> = Erik.visitFuture(url: url)
// fill input field
future = future.flatMap { document -> Future<Document, NSError> in
    if let input = document.querySelector("input[name='q']") {
        input["value"] = value
    }
    if let form = document.querySelector("form[name=\"f\"]") as? Form {
        form.submit()
    }
    return Erik.currentContentFuture()
}
// finally get final result as success or error
future.onSuccess { document in
    // parse result
}
future.onFailure { error in
    print("\(error)")
}

局限性

在 iOS 9 和 macOS 10.11 上,您需要确保使用 https://,因为 iOS 9 和 macOS 10.11 不喜欢应用以不安全的方式发送或接收数据。 如果您想覆盖此设置,请点击此处阅读关于 App Transport Security 的信息。

链接

设置

使用 CocoaPods

CocoaPods 是 Objective-C 和 Swift 的集中式依赖管理器。点击此处了解更多。

  1. 将项目添加到您的 Podfile 中。

    use_frameworks!
    
    pod 'Erik'
    // or specific target
    target :test do
       pod 'Erik'
    end
  2. 运行 pod install 并打开 .xcworkspace 文件以启动 Xcode。

可选的 Future

pod 'Erik/Future' 添加到您的 Podfile 中并运行 pod install

使用 Carthage

Carthage 是 Objective-C 和 Swift 的去中心化依赖管理器。

  1. 将项目添加到您的 Cartfile 中。

    github "phimage/Erik"
    

路线图

为什么选择 Erik?

一个著名的无头浏览器名为 PhantomJS,而一个非常著名的浏览器是 Opera

为了致敬,我使用了 Erik,这是加斯顿·勒鲁小说《歌剧魅影》(Le Fantôme de l'Opéra)主角的名字,英文读者更熟悉的名字是 《歌剧魅影》(The Phantom of Opera)。

我的名字也是 Erik。 用自己的名字来命名一个项目,是不是很自恋呢。

我唯一的理由是,我当时在玩《合金装备 V》,游戏创作者小岛秀夫的名字在游戏中出现了 100 多次。巧合的是,游戏的完整名称是《合金装备 V:幻痛》。

许可证

MIT 许可证。 有关更多信息,请参阅 LICENSE 文件。