有如下的HTML/XML文件:


"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

"zh-CN">

"Content-Type" content="text/html;charset=utf-8" />

    "Referrer" content="unsafe-url" />

        "True" name="HandheldFriendly" />

            "theme-color" content="#333344" />

                

                "detectify-verification" content="d0264f228155c7a1f72c3d91c17ce8fb" />

                    "alexaVerifyID" content="OFc8dmwZo7ttU4UCnDh1rKDtLlY" />

                        "baidu-site-verification" content="D00WizvYyr" />

                            "msvalidate.01" content="D9B08FEA08E3DA402BF07ABAB61D77DE" />

                                "wb:webmaster" content="f2f4cb229bda06a4" />

                                    "google-site-verification" content="LM_cJR94XJIqcYJeOCscGVMWdaRUvmyz6cVOqkFplaU" />

                                        

                                        V2EX  <span style="line-height:normal;font-family:'PingFang SC';">我收藏的主题</span>

"dns-prefetch" href="//static.v2ex.com" />

    "dns-prefetch" href="//cdn.v2ex.com" />

        "dns-prefetch" href="//cdn.v2ex.co" />

            "dns-prefetch" href="//i.v2ex.co" />

                

                "stylesheet" type="text/css" media="screen" href="/css/basic.css?v=228347:1493519627:3.9.7.5" />

                    

                    "stylesheet" type="text/css" media="screen" href="/static/css/style.css?v=b1d9e9c39b16b1c91b7e03ac0c2d412c" />

                        "stylesheet" type="text/css" media="screen" href="/css/desktop.css?v=3.9.7.5" />

                            "stylesheet" href="//v2ex.assets.uxengine.net/js/highlight/styles/tomorrow.css" type="text/css" />

                               

"icon" sizes="192x192" href="/static/img/v2ex_192.png" />

    "shortcut icon" href="/static/img/icon_rayps_64.png" type="p_w_picpath/png" />

        "stylesheet" type="text/css" href="/static/css/font-awesome.min.css?v=295235b28b6e649d99539a9d32b95d30" />

           

"/static/css/jquery.textcomplete.css?v=5a041d39010ded8724744170cea6ce8d" rel="stylesheet" />

   

"/static/js/select2/select2.css?v=2621fe97ae1aabca8661d60000147412" rel="stylesheet" />

   

"/static/js/selectboxit/selectboxit.css?v=5dc55d3860ef80ef1875d6800a5fbfa3" rel="stylesheet" >

   

"description" content="" />

    

       

"Top">

class="content">

"padding-top: 6px;">

"0" cellspacing="0" border="0" width="100%">

"110" align="left">"/" name="top" title="way to explore">"//v2ex.assets.uxengine.net/site/logo@2x.png?m=1346064962" border="0" align="default" alt="V2EX" width="94" height="30" /> "auto" align="left">

"Search">
"https://www.google.com" onsubmit="return dispatch()" target="_blank">
"width: 276px; height: 28px; background-size: 276px 28px; background-p_w_picpath: url('/static/img/qbar_light@2x.png'); background-repeat: no-repeat; display: inline-block;">"text" maxlength="40" name="q" id="q" value="" />

"570" align="right" style="padding-top: 2px;">"/" class="top">首页   "/member/duwei1" class="top">duwei1   "/settings" class="top">设置   "#;" onclick="if (confirm('确定要从 V2EX 登出?')) { location.href= '/signout?once=29225'; }" class="top">登出

"Wrapper">

class="content">


"Leftbar">

"Rightbar">

class="sep20">



class="box">

class="cell">

"0" cellspacing="0" border="0" width="100%">

"48" valign="top">"/member/duwei1">"//v2ex.assets.uxengine.net/gravatar/2067bb823aa712eb75ab19b6b150d658?s=48&d=retro" class="avatar" border="0" align="default" style="max-width: 48px; max-height: 48px;" /> "10" valign="top"> "auto" align="left">class="bigger">"/member/duwei1">duwei1


class="sep10">

"0" cellspacing="0" border="0" width="100%">

"33%" align="center">"/my/nodes" class="dark" style="display: block;">class="bigger">0
class="sep3">
class="fade">节点收藏
"34%" style="border-left: 1px solid rgba(100, 100, 100, 0.4); border-right: 1px solid rgba(100, 100, 100, 0.4);" align="center">"/my/topics" class="dark" style="display: block;">class="bigger">5
class="sep3">
class="fade">主题收藏
"33%" align="center">"/my/following" class="dark" style="display: block;">class="bigger">0
class="sep3">
class="fade">特别关注

class="cell">

"width: 250px; background-color: #f0f0f0; height: 3px; display: inline-block; vertical-align: middle;">
"width: 42px; background-color: #ccc; height: 3px; display: inline-block;">


class="cell" style="padding: 5px;">

"0" cellspacing="0" border="0" width="100%">

"32">"/new">"/static/img/flat_compose.png?v=7d21f0767aeba06f1dec21485cf5d2f1" width="32" border="0" /> "10"> "auto" valign="middle" align="left">"/new">创作新主题


class="dock_area">




class="sep20">





class="sep20">



"Main">

class="sep20">

class="box">

class="header">"/">V2EX class="chevron">   我收藏的主题
class="fr f12">class="snow">主题总数  class="gray">5




class="cell item" style="">

"0" cellspacing="0" border="0" width="100%">



"48" valign="top" align="center">"/member/Diss">"//v2ex.assets.uxengine.net/avatar/e4a7/67a3/94330_normal.png?m=1422432421" class="avatar" border="0" align="default" /> "10"> "auto" valign="middle">class="item_title">"/t/358175#reply1">腾讯云采购节 腾讯云 7.9 官网折扣折上折

class="sep5">

class="small fade">

class="votes">
class="node" href="/go/cloud">云计算    "/member/Diss">Diss    5 分钟前    最后回复来自 "/member/ik">ik

"70" align="right" valign="middle">


"/t/358175#reply1" class="count_livid">1





class="cell item" style="">

"0" cellspacing="0" border="0" width="100%">



"48" valign="top" align="center">"/member/lishunli">"//v2ex.assets.uxengine.net/gravatar/bf971b40c441ad731d7a3eb147473c69?s=48&d=retro" class="avatar" border="0" align="default" /> "10"> "auto" valign="middle">class="item_title">"/t/358153#reply25">vultr 一到晚上丢包就太严重了

class="sep5">

class="small fade">

class="votes">
class="node" href="/go/cloud">云计算    "/member/lishunli">lishunli    4 分钟前    最后回复来自 "/member/watara">watara

"70" align="right" valign="middle">


"/t/358153#reply25" class="count_livid">25



class="cell item" style="">

"0" cellspacing="0" border="0" width="100%">



"48" valign="top" align="center">"/member/lbc307">"//v2ex.assets.uxengine.net/gravatar/8a1fb736bbefe5c627301b5e289a2828?s=48&d=retro" class="avatar" border="0" align="default" /> "10"> "auto" valign="middle">class="item_title">"/t/358125#reply30">新手,我在自学编程当中遇到的一些问题。

class="sep5">

class="small fade">

class="votes">
class="node" href="/go/java">Java    "/member/lbc307">lbc307    8 分钟前    最后回复来自 "/member/humor66">humor66

"70" align="right" valign="middle">


"/t/358125#reply30" class="count_livid">30






class="c">

class="sep20">

"Bottom">

class="content">

class="inner">

class="sep10">

"/about" class="dark" target="_self">关于   class="snow">·   "/faq" class="dark" target="_self">FAQ   class="snow">·   "/p/7v9TEc53" class="dark" target="_self">API   class="snow">·   "/mission" class="dark" target="_self">我们的愿景   class="snow">·   "/advertise" class="dark" target="_self">广告投放   class="snow">·   "/advertise/2016.html" class="dark" target="_self">鸣谢   class="snow">·   1078 人在线   class="fade">最高记录 2466   class="snow">·   "/select/language">"/static/img/lang_zhcn_32.png" align="absmiddle" border="0" width="20" alt="" />

class="sep20">

创意工作者们的社区

class="sep5">

World is powered by solitude

class="sep20">

class="small fade">VERSION: 3.9.7.5 · 35ms · UTC 02:45 · PVG 10:45 · LAX 19:45 · JFK 22:45
Do have faith in what you're doing.

class="sep20">

class="f12 gray">"http://www.miibeian.gov.cn/" target="_blank" rel="nofollow">ICP16043287-1

class="sep10">





显示的web图片在上传文件中。


解析的过程如下:


   /**

     获取我的收藏帖子列表


     */

    class func getFavoriteList(_ page:Int = 1, completionHandler: @escaping (V2ValueResponse<([TopicListModel],Int)>) -> Void){

        //先获取请求地址,如: https://www.v2ex.com/my/topics?p=1

        

        Alamofire.request(V2EXURL+"my/topics?p=\(page)", headers: MOBILE_CLIENT_HEADERS).responseJiHtml { (response) -> Void in

            var resultArray:[TopicListModel] = []

            var maxPage = 1

            if let jiHtml = response.result.value {

                // 先找到 class="cell item" 的这个节点

                

                if let aRootNode = jiHtml.xPath("//*[@class='cell item']"){

                    for aNode in aRootNode {

                        let topic = TopicListModel(favoritesRootNode:aNode)

                        resultArray.append(topic);

                    }

                }

                //更新通知数量

                V2User.sharedInstance.getNotificationsCount(jiHtml.rootNode!)


                //获取最大页码 只有第一页需要获取maxPage

                if page <= 1

                    ,let aRootNode = jiHtml.xPath("//*[@class='page_normal']")?.last

                    , let page = aRootNode.content

                    , let pageInt = Int(page)

                {

                    maxPage = pageInt

                }

            }


            let t = V2ValueResponse<([TopicListModel],Int)>(value:(resultArray,maxPage), success: response.result.isSuccess)

            completionHandler(t);

        }

    }


 //////////////////////////////


    if let aRootNode = jiHtml.xPath("//*[@class='cell item']"){

                    for aNode in aRootNode {

                        let topic = TopicListModel(favoritesRootNode:aNode)

                        resultArray.append(topic);

                    }

                }


这部分是主要的,找到节点。


init(favoritesRootNode:JiNode) {

        super.init()

        self.avata = favoritesRootNode.xPath("./table/tr/td[1]/a[1]/img[@class='avatar']").first?["src"]

        self.nodeName = favoritesRootNode.xPath("./table/tr/td[3]/span[2]/a[1]").first?.content

        self.userName = favoritesRootNode.xPath("./table/tr/td[3]/span[2]/strong[1]/a").first?.content


        let node = favoritesRootNode.xPath("./table/tr/td[3]/span/a[1]").first

        self.topicTitle = node?.content

        self.setupTitleLayout()


        var topicIdUrl = node?["href"];


        if var id = topicIdUrl {

            if let range = id.range(of: "/t/") {

                id.replaceSubrange(range, with: "");

            }

            if let range = id.range(of: "#") {

                id = id.substring(to: range.lowerBound)

                topicIdUrl = id

            }

        }

        self.topicId = topicIdUrl



        let date = favoritesRootNode.xPath("./table/tr/td[3]/span[2]").first?.content

        if let date = date {

            let array = date.components(separatedBy: "")

            if array.count == 4 {

                self.date = array[3].trimmingCharacters(in: NSCharacterSet.whitespaces)

                

            }

        }


        self.lastReplyUserName = favoritesRootNode.xPath("./table/tr/td[3]/span[2]/strong[2]/a[1]").first?.content


        self.replies = favoritesRootNode.xPath("./table/tr/td[4]/a[1]").first?.content

    }


这个方法里面代码的作用是解析得到cell中模型的数据。比如cell中的一个模型数据为userName,有一个值为lishunli,根据favoritesRootNode.xPath("./table/tr/td[3]/span[2]/strong[1]/a").first?.content后进行赋值。


解析后赋值给模型的图片在上传文件中。