为了账号安全,请及时绑定邮箱和手机立即绑定

用Kotlin开发了一个Android应用,我只用了8小时

标签:
Kotlin

爬取数据

网站非常规律,看看jsoup用法很容易就搞到手啦,下面是详细方法.

首先,我们打开网站,查看网页源代码,可以看到各个分类的网址,待会儿我们可以根据用户选择的分类去爬对应分类的数据.

webp

然后再来看看,每个分类首页(第一页)其实是有一些图片,我们待会儿需要筛选出这些图片的详情页地址,并且这些图片地址我们可以用来展示到app的分类首页上.其实各分类是不止一页的,它们的规律是从第二页末尾就是index_x.shtml结尾,其中x为当前页索引.http://www.msgao.com/dqfl/om/index_2.shtml

webp

我们使用Jsoup开源库去爬取数据,关于Jsoup,其实使用起来非常简单,而且官方还非常人性化的有中文文档,地址.


首先,我们是通过以下方式连接上url

   //连接

    val document: Document = Jsoup.connect(buildUrl).get()

然后我们筛选那些有图片链接的

//筛选首页全部的链接   暂时是第一页的

val htmls: Elements = document.select("a[href$=.shtml]")

//筛选是可以点击进去详情的url

htmls.forEachReversedByIndex {

   val realUrl = it.getElementsByClass("div-img")

   //不正确的全部移除

   if (realUrl.size == 0) {

       htmls.remove(it)

   }

}

接着是获取图片地址和图片标题

//外层列表的bean集合

val outLists: ArrayList<DivListImgBean> = ArrayList()

htmls.forEach {

   val divListImgBean = DivListImgBean("", "","")

   val linkElements = it.getElementsByClass("link")

   divListImgBean.detailsUrl = linkElements.attr("href")

   //获取图片地址

   val imgSrcs = it.select("img[src\$=.jpg]")

   imgSrcs.forEach {

       val src = it.attr("src")

       val alt = it.attr("alt")

       divListImgBean.src = src

       divListImgBean.text = alt

   }

   //添加bean到集合中

   outLists.add(divListImgBean)

}

加入用户点击了某个图片链接,我们就去抓取图片详情页,所有的图片链接,进行该美女的详情展示.在方法上和上面的方法大同小异.

看代码吧,比我说的更清楚.结合jsoup 开发文档和网页源码一起看哟

import com.xfhy.deeplibrary.common.LogUtil

import com.xfhy.deepnight.bean.DivListImgBean

import org.jetbrains.anko.collections.forEachReversedByIndex

import org.jetbrains.anko.doAsync

import org.jetbrains.anko.uiThread

import org.jsoup.Jsoup

import org.jsoup.nodes.Document

import org.jsoup.select.Elements

/**

* @author xfhy

* create at 2018/1/1 12:36

* description:

*/

object NetUtils {

   /**

    * 获取外部的列表页的list

    * @param url url

    * @param index 索引  从1开始

    * @param response 回调数据

    */

   fun reqOutList(url: String, index: Int, response: ZResponse) {

       doAsync {

           try {

               //组装url

               var buildUrl = "${url}index${if (index == 1) "" else "_$index"}.shtml"

               LogUtil.e("buildUrl = $buildUrl")

               //连接

               val document: Document = Jsoup.connect(buildUrl).get()

               //筛选首页全部的链接   暂时是第一页的

               val htmls: Elements = document.select("a[href$=.shtml]")

               //筛选是可以点击进去详情的url

               htmls.forEachReversedByIndex {

                   val realUrl = it.getElementsByClass("div-img")

                   //不正确的全部移除

                   if (realUrl.size == 0) {

                       htmls.remove(it)

                   }

               }

               //外层列表的bean集合

               val outLists: ArrayList<DivListImgBean> = ArrayList()

               htmls.forEach {

                   val divListImgBean = DivListImgBean("", "","")

                   val linkElements = it.getElementsByClass("link")

                   divListImgBean.detailsUrl = linkElements.attr("href")

                   //获取图片地址

                   val imgSrcs = it.select("img[src\$=.jpg]")

                   imgSrcs.forEach {

                       val src = it.attr("src")

                       val alt = it.attr("alt")

                       divListImgBean.src = src

                       divListImgBean.text = alt

                   }

                   //添加bean到集合中

                   outLists.add(divListImgBean)

               }

               LogUtil.e(outLists.toString())

               uiThread {

                   response.onSuccess(outLists)

               }

           } catch (e: Exception) {

               uiThread {

                   response.onError(e.message)

               }

           }

       }

   }

   /**

    * 详情列表

    */

   fun reqDetails(url: String, response: ZResponse) {

       doAsync {

           try {

               //连接

               val document: Document = Jsoup.connect(url).ignoreContentType(true).get()

               val girlPictureList = document.select("div.div-num")

               val imageList: ArrayList<String> = ArrayList()

               girlPictureList.forEach {

                   if (it.hasAttr("data-src")) {

                       var imgUrl = it.attr("data-src")

                       imgUrl = imgUrl.substring(0, imgUrl.indexOf("?"))

                       imageList.add(imgUrl)

                   }

               }

               LogUtil.e(imageList.toString())

               uiThread {

                   response.onSuccess(imageList)

               }

           } catch (e: Exception) {

               uiThread {

                   response.onError(e.message)

               }

           }

       }

   }

}

构建UI

UI交互上,我是采用的侧滑风格的app,中间的数据全部采用fragment来填充的,fragment只有在显示后才加载数据(懒加载机制),不会浪费过多流量。素材取自阿里矢量图标库.阿里妈妈MUX倾力打造的矢量图标管理、交流平台。设计师将图标上传到Iconfont平台,用户可以自定义下载多种格式的icon,平台也可将图标转换为字体,便于前端工程师自由调整与调用。下载图标完全免费,而且还可以调整颜色和大小,更有SVG下载,简直爽翻天.对于我这种一点儿也不会制作图标的菜鸟级程序员来说,简直就是福利。

webp

总结

其实,将一个没有防爬的网站撸成app还是比较简单的,基本上都是这个套路,大家也可以试试.比如内涵段子等,做成app,然后平时可以自己用,还可以给朋友用,还锻炼了自己所学的知识,何乐而不为呢。

Kotlin开发起来真的很顺手,也很方便,就像平时说话一样,很顺畅.大家要学习Kotlin的话,建议多看看kotlin的官方文档。



作者:Android开发架构
链接:https://www.jianshu.com/p/6f1315f44b19


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消