Android Jsoup爬取网页数据及其局限性,接口爬取数据的思路

  • Post author:
  • Post category:其他


1.Jsoup

jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过

DOM,CSS以及类似于jQuery

的操作方法来取出和操作数据。

需求是需要获取某个网站上的排行榜数据,用作App展示,所以就想到了Jsoup框架。

我看网上其实有很多的Jsoup博客,讲的挺好的,但是有些许差异,有的也将错了,我还是推荐去


官网学习,


内容很少,也很简便:


Load a Document from a URL: jsoup Java HTML parser

里面讲了如何从html文件,url地址,file加载内容,也讲了通过

DOM,CSS以及类似于jQuery

的操作方法来取出和操作数据,很详细也写的挺简单的,是全英文,看不太懂可以装个翻译插件,或者google浏览器翻个墙,他自己就给你翻译了。

这里我就不详细展开了,很多很杂但也很基础,讲个例子吧:比如获取2022年billboard榜单的前100位歌手数据(排名,封面,名字)


Top Artists – Billboard


实现代码:Kotlin

1.使用getListData方法获取歌手信息列表;

2.

Dispatchers.IO

– 此调度程序经过了专门优化,适合在主线程之外执行磁盘或网络 I/O。示例包括使用Room组件、从文件中读取数据或向文件中写入数据,以及运行任何网络操作。

3.Jsoup.connect(url).get()获取到Document对象,拿到对象后,就可以用那几种方式获取自己想要的数据了。

    fun getListData(result:RequestCallBack<MutableList<ArtistInfo>>): List<ArtistInfo>? {
        CoroutineScope(Dispatchers.IO).launch {
            val artistList = mutableListOf<ArtistInfo>()
            val url = "https://www.billboard.com/charts/year-end/top-artists/"
            try {
                val document = Jsoup.connect(url).get()
                Log.d("TTTT", "jsoup:$document")
                val listDoc: Elements =
                    document.getElementsByClass("o-chart-results-list-row-container")
                Log.d("TTTT", "jsoup:size ${listDoc.size}")
                val artistSize = if (listDoc.size > 50) 50 else listDoc.size
                for (i in 0 until artistSize) {
                    val sortNum = listDoc[i].select("span").text()
                    Log.d("TTTT", "jsoup:$sortNum")
                    val artistName = listDoc[i].select("h3").text()
                    Log.d("TTTT", "jsoup:$artistName")
                    val img = listDoc[i].select("img").attr("data-lazy-src").toString()
                    Log.d("TTTT", "jsoup:$img")
                    val artistInfo = ArtistInfo().apply {
                        this.artist = artistName
                        this.rank = sortNum.toInt()
                        this.coverOnline = img
                    }
                    artistList.add(artistInfo)//加入列表
                    App.getInstance().getArtistDao().insertOrReplace(artistInfo)//单个歌手数据插入数据库,用的greenDao
                }
                result.success(artistList)//返回歌手列表数据,UI上展示

            } catch (exception: IOException) {
                exception.printStackTrace()
            }
        }
        return null
    }

当然,怎么去知道网页的数据在何种标签,哪个class下面呢,自然是去浏览器F12查看数据咯

1.首先是element查看当前网页的源代码,在旁边的黄色标记的箭头,你点击后,再去点左边网页的元素,你就知道,它的数据在哪里了。

2.在network中,点到返回的各个数据中,选到response就可以看到,请求返回的数据,也可以观察其数据结构(有js、json等数据格式)

这个框框里的选项很有用,可以看到请求方式,参数,预览页,返回数据等等

2.局限性

使用Jsoup还是挺快乐的,我在爬取国内大多数的网站的时候,大多数的数据都可以拿到。

但是,我在爬取某些网页的时候,发现某些数据拿不到,拿不全,我发现有些网页,他的数据并不是一次获取的,按F12发现,他会并行请求很多数据再展示,所以,

Jsoup是否可以真的获得动态网页的数据吗???


我在

百度Jsoup 爬取动态网页发现一堆文章,但是我看其文章其实爬的数据都是一次性拿到的,真的懵逼。

Jsoup是否有局限性呢?


所以我个人觉得Jsoup爬虫,该方式是有一定局限性的,就是你通过jsoup爬虫更适合爬静态网页,所以不特殊配制的情况下只能爬当前页面的部分数据。如果需要爬一个网站所有数据,通过接口,通过上传正确的参数,或许更容易爬到该网站的该有的数据信息。

emmmm,在爬取一个网站的音乐数据时,用Jsoup好久都没搞出来。最后还是F12查询接口,参数用接口获取到的数据。

接口获取数据的话,繁琐些,但是如果网站没做反爬虫,拿取数据还是没问题的。


tips:Jsoup或许可以通过配置请求体(data),配置header那些去获取动态网页的数据,但是个人觉得有些麻烦,爬的页面有点多,还是选择了接口


3.接口爬取数据思路

主要流程:

1.目标网页,看下图,观察header等等里面的数据,获取接口,需要的参数等等

2.这时候你会发现,接口返回的response里的Json数据,这可怎么看啊??这儿推荐一个超级好用的网址。


Online JSON Viewer

3.有网址了先别急,先用postman去模拟访问数据,看自己配的数据是否真的可以访问网址并获取到争取的数据。postman拿到的数据也可以放到上面的网址里面去查看数据结构,因为网址接口爬取的数据会很大,postman不好观察。

4.建立请求/返回的实体类,然后用android网络框架去访问它就行了。

这儿只提供下思路,具体实现就不说了。思路有了做起来很快的。

个人爬取数据仅作个人学习,老铁们记得好自为之啊,哈哈哈



版权声明:本文为LoveFHM原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。