如何使用 Swift 从 URL 获取 HTML 源代码

Posted

技术标签:

【中文标题】如何使用 Swift 从 URL 获取 HTML 源代码【英文标题】:How To Get HTML source from URL with Swift 【发布时间】:2014-11-25 21:51:56 【问题描述】:

我需要查看某个 URL 给出的页面的 html。如果我有这个,使用 Swift 获取该 URL 的 HTML 源的最有效和同步的方法是什么?我一直无法在网上找到一种简洁的方式将其返回到变量中,而不是在完成处理程序中打印它。

我需要在使用 URL 的任何调用之外操作源。这在 Swift 中是如何完成的?

【问题讨论】:

给读者的友情提示:这个问题专门针对 同步 方法。如果您不是特别需要,请不要使用这些答案。正常的方法是使用 asynchronous 方法。谢谢。 【参考方案1】:

免责声明:由于这获得了相当多的意见,我只想提醒大家,这里的答案是同步的,如果你在主线程上这样做会阻塞你的应用程序。您应该始终异步执行此操作(在后台线程中),但问题要求使用同步方法,因此此处无法解释如何执行此操作。


你应该看看方法:

+ stringWithContentsOfURL:encoding:error (docs)

你可以在 Objective C 中这样称呼它:

NSString *myURLString = @"http://google.com";
NSURL *myURL = [NSURL URLWithString:myURLString];

NSError *error = nil;
NSString *myHTMLString = [NSString stringWithContentsOfURL:myURL encoding: NSUTF8StringEncoding error:&error];

if (error != nil)

    NSLog(@"Error : %@", error);

else

    NSLog(@"HTML : %@", myHTMLString);

所以在 Swift 3 和 4 中,等价的应该是:

let myURLString = "https://google.com"
guard let myURL = URL(string: myURLString) else 
    print("Error: \(myURLString) doesn't seem to be a valid URL")
    return


do 
    let myHTMLString = try String(contentsOf: myURL, encoding: .ascii)
    print("HTML : \(myHTMLString)")
 catch let error 
    print("Error: \(error)")

您可能希望根据您的页面使用的编码来调整编码(请参阅constants)。


旧答案,Swift 2.2:

let myURLString = "http://google.com"
guard let myURL = NSURL(string: myURLString) else 
    print("Error: \(myURLString) doesn't seem to be a valid URL")
    return


do 
    let myHTMLString = try String(contentsOfURL: myURL)
    print("HTML : \(myHTMLString)")
 catch let error as NSError 
    print("Error: \(error)")


旧答案,Swift 1.2:

let myURLString = "http://google.com"

if let myURL = NSURL(string: myURLString) 
    var error: NSError?
    let myHTMLString = NSString(contentsOfURL: myURL, encoding: NSUTF8StringEncoding, error: &error)

    if let error = error 
        println("Error : \(error)")
     else 
        println("HTML : \(myHTMLString)")
    
 else 
    println("Error: \(myURLString) doesn't seem to be a valid URL")

【讨论】:

contentsOfURL: myURL 抛出一个问题“可选类型'NSURL的值?'没有展开。无法编辑,因为只有一个标志。【参考方案2】:

@DCMaxx 对 Swift 2.2 的更新回答:

let myURLString = "http://www.yahoo.com"

if let myURL = NSURL(string: myURLString) 
    var error: NSError?
    let myHTMLString = try! NSString(contentsOfURL: myURL, encoding: NSUTF8StringEncoding)

    if let error = error 
        print("Error : \(error)")
     else 
        print("HTML : \(myHTMLString)")
    
 else 
    print("Error: \(myURLString) doesn't  URL")

【讨论】:

您已经在代码中声明了一个变量error ,它根本从未使用过,另一个非常重要的事情是您正在使用try! 禁用错误传播,但不建议这样做,因为您告诉编译器您永远不会收到错误,但如果收到它,您将遇到运行时错误,使用地址"http://www.asdsadsadas,com" 对其进行测试,您将遇到运行时错误。【参考方案3】:

这是 Swift 2 的发展方向:

let myURLString = "https://duckduckgo.com/"

if let myURL = NSURL(string: myURLString) 

    do 
        let myHTMLString = try String(contentsOfURL: myURL, encoding: NSUTF8StringEncoding)
        print("HTML : \(myHTMLString)")
     catch 
        print("Error : \(error)")
    
 else 
    print("Error: \(myURLString) doesn't  URL")

也作为与先前答案相关的额外: 请注意,Swift 2 引入了一种新的错误处理方法,该方法可以生成更清晰的代码供程序员阅读,它消除了诸如 & 传递 NSErrors 之类的复杂性,并通过确保捕获所有错误为您提供更高的安全性。

如果您 100% 确定呼叫不会失败,请仅使用 try!

延伸阅读: https://www.hackingwithswift.com/new-syntax-swift-2-error-handling-try-catch

【讨论】:

【参考方案4】:

斯威夫特 3:

    if let url = URL(string: "https://www.google.com/trends/hottrends/atom/hourly") 
        do 
            let contents = try String(contentsOf: url)
            print(contents)
         catch 
            // contents could not be loaded
        
     else 
        // the URL was bad!
    

【讨论】:

【参考方案5】:

更紧凑的函数示例

let myURLString = "https://google.com"

let myHTMLString = try URL(string: myURLString)
    .flatMap  try Data(contentsOf: $0) 
    .flatMap  String(data: $0, encoding: .ascii) 

【讨论】:

以上是关于如何使用 Swift 从 URL 获取 HTML 源代码的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 4 中从图像选择器获取照片本地 url

Swift - 使用 SwiftyJSON 从 JSON 中获取字符串数组

如何在 Swift 中使用 URL 从库中获取图像? [复制]

如何从 Swift 3 xcode8 的 UIWebView 中的 url 获取查询字符串参数?

从 URL 获取 UIView 的图像 [Swift]

如何使用 Swift 从 NSURLSession 获取 cookie?