使用Kanna

时间:2017-08-04 18:00:00

标签: html swift parsing xpath

Google图片搜索会返回如下结果链接:

<div class="rg_meta notranslate">{"cb":6,"cl":21,"cr":9,"ct":6,"id":"G9X757bOKIt_dM:","isu":"hitparade.ch","itg":0,"ity":"jpg","oh":300,"ou":"http://streamd.hitparade.ch/cdimages/jennifer_rush-i_come_undone_s.jpg","ow":296,"pt":"Jennifer Rush - I Come Undone - hitparade.ch","rid":"xArn9C5TiVuF9M","rmt":0,"rt":0,"ru":"http://hitparade.ch/song/Jennifer-Rush/I-Come-Undone-1581","s":"Jennifer Rush - I Come Undone","sc":1,"st":"Hitparade.ch","th":226,"tu":"https://encrypted-tbn0.gstatic.com/images?q\u003dtbn:ANd9GcRbLwVl711N3Q93C-SFdj1a1X6CLQIohPbb_8G9eBEJBX_bzQdC","tw":223}</div>

如何在此div中正确获取图像路径(在&#34; ou&#34;字段中)

rg_meta
与Swift和Kanna合作? 我尝试了几种变体,例如

// Alamofire.request...
if let doc = Kanna.HTML(html: html, encoding: String.Encoding.utf8) {
    for item in doc.xpath("//div[@class='rg_meta']") {
        print(item.text)
        print(item["ou"])
    }
}

但该项目始终为空。这个Json数据在div中吗?有没有办法获得&#34; ou&#34;与Kanna的领域? 感谢。

编辑: 生成用于测试xpath表达式的html的示例是:

https://www.google.com/search?q=jennifer+rush+i+come+undone&gbv=2&tbm=isch

EDIT2:

好的,虽然Adrians的回答似乎正确地捕获了字段中的json数据&#34; ou&#34;,但我的代码仍未按预期工作,我做了一些调试:

正如我现在看到的,我的主要问题似乎是我打算捕获的div类不是由Alamofire下载的。这似乎是因为这不是在谷歌回归的html体内,但远远低于我不理解的结构。可以在搜索结果的源代码中看到它。

到目前为止我的测试代码:

    let requestUrl = "https://www.google.com/search?q=jennifer+rush+i+come+undone&gbv=2&tbm=isch"
    Alamofire.request(requestUrl).responseString { response in
        print("Request success/charcount: \(response.result.isSuccess) \(response.result.value?.characters.count ?? 0)")
        if let responseHtml = response.result.value {
            if let doc = Kanna.HTML(html: responseHtml, encoding: String.Encoding.utf8) {
                for item in doc.xpath("//div[@class='rg_meta']") {
                    print(item.text ?? "---")
                }
            }
        }
    }

输出:

Request success/charcount: true 40830

下载了40k html,但在浏览器中查看的整个源代码大约为600k。有没有办法下载所有内容,以便我可以搜索特殊的div类? 我试过了

Alamofire.request(requestUrl).responseData

Alamofire.download(requestUrl, to: destination)

也是,但都返回了40k html。

谢谢,

1 个答案:

答案 0 :(得分:1)

let yourText = "<div class=\"rg_meta notranslate\">{\"cb\":6,\"cl\":21,\"cr\":9,\"ct\":6,\"id\":\"G9X757bOKIt_dM:\",\"isu\":\"hitparade.ch\",\"itg\":0,\"ity\":\"jpg\",\"oh\":300,\"ou\":\"http://streamd.hitparade.ch/cdimages/jennifer_rush-i_come_undone_s.jpg\",\"ow\":296,\"pt\":\"Jennifer Rush - I Come Undone - hitparade.ch\",\"rid\":\"xArn9C5TiVuF9M\",\"rmt\":0,\"rt\":0,\"ru\":\"http://hitparade.ch/song/Jennifer-Rush/I-Come-Undone-1581\",\"s\":\"Jennifer Rush - I Come Undone\",\"sc\":1,\"st\":\"Hitparade.ch\",\"th\":226,\"tu\":\"https://encrypted-tbn0.gstatic.com/images?q\\u003dtbn:ANd9GcRbLwVl711N3Q93C-SFdj1a1X6CLQIohPbb_8G9eBEJBX_bzQdC\",\"tw\":223}</div>"

// You can use some other method to extract the text from the div 
let rawJson = yourText
    .components(separatedBy: "<div class=\"rg_meta notranslate\">").last!
    .components(separatedBy: "</div>").first!


guard let jsonObject = try? JSONSerialization.jsonObject(with: rawJson.data(using: .utf8)!, options: []),
    let json = jsonObject as? [AnyHashable : Any]
else {
    return
}

print(json["ou"])