「Kotlin 101」下载必应每日一图
记得之前在学 Python 爬虫的时候,那必应的每日一图练过手。这次看看如何用 Kotlin 实现必应每日一图的下载。
本文的主要目的,是为了熟悉 Kotlin 使用。
思路
把大象放进冰箱要几步?……啊,不对,此处应是“把网络上的一个图片下载下来需要几步”?
真的很“简单”:
- 获取图片下载链接
- 下载图片
- 保存图片到文件
跟“大象放冰箱”一样,也是三步,但其实理解每一步的知识点,就不难。
步骤
1. 获取图片下载链接
这里涉及到一个知识点:Json 反序列化。
以前为了获取图片的下载链接,需要解析文档,但现在 Bing 提供了一个 API 直接获取图片的下载链接。
1 | https://cn.bing.com/hp/api/model |
这个 API 返回的是 Json 格式的字符串,里面包含了图片的下载地址。
这里返回了一堆,不太好看,可以找个在线格式化 Json 字符串的网站看下。
这里 Url
对应的值即为图片下载地址的 Path
。当然,它并不完整,需要加上域名后才是完整的下载链接。
1 | https://cn.bing.com/th?id=OHR.Invergarry_EN-CN6569359503_1920x1080.jpg&rf=LaDigue_1920x1080.jpg |
那么,回到主题,在 Kotlin 代码中如何解析 Json 呢?
可能有的小伙伴会想到 Gson
,确实,这是一个非常强大的序列化/反序列化的三方库,它也支持 Kotlin。但今天,这里使用 Kotlin 官方的一个序列化/反序列化库:kotlin serialization
。
引入Kotlin serialization
我这里使用的了 Kotlin DSL 作为构建语言,因此需要在 build.gradle.kts
中,添加如下字段:
1 | plugins { |
如果你使用的是 Groovy
,请在 build.gradle
中完成修改。
定义数据结构
kotlin serialization
支持两种操作:
- 将一个对象序列化为 Json 字符串
- 将 Json 字符串反序列化成一个对象
这一切是有前提的,就是我们必须定义,并通过特定注解修饰这个对象的数据结构。
这里使用到了 @Serializable
,目的是告诉 Kotlin serialization
如何序列化/反序列化该对象。
1 |
|
建议对照 Json 格式化后的结果看上述代码。
反序列化生成对象
1 | private val json = Json { ignoreUnknownKeys = true } |
这里有一个坑,注意在构建 Json 对象(用于序列化和反序列化)时,ignoreUnknownKeys
必须设为 true
,因为我们并没有把返回的所有 Json 元素都反序列化,只时挑出了我们需要的部分。而 kotlin serialization
是默认需要反序列化所有元素的,因此这里需要显示指明。
2. 下载图片
由于要从网上访问资源,所以这里需要熟悉 Kotlin 中网络接口相关的API/三方库。
三方库可以选用 OkHttp
或者 Ktor
,但考虑到 Kotlin 是完全兼容 Java 的,所以还可以使用 JDK 中的 URL
和HttpClient
/HttpRequest
。
1 | /** |
3. 将图片保存到文件
第2步中已经实现了。