Java爬虫实践之获取历史上的今天

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java爬虫实践之获取历史上的今天相关的知识,希望对你有一定的参考价值。

概述

我们可以在一些网站上看到一些文字,显示了历史上的今天发生了什么事情。例如CSDN的登录页面:
而我们今天的目标是百度搜索上显示的历史上的今天,如下:

(注:图片无法显示)

通过历史上的今天访问查看

我们需要获取“历史上的今天”的所有事件,然后可以把这些数据显示在自己的网站上,就可以给自己网站上也增加一个“历史上的今天”的功能。

准备

要想使用这个爬虫,需要如下知识:

  • hutool的hutool-http模块
  • Gson
  • Jsoup

其中hutool-http模块需要用来发送HTTP请求,请求URL,返回服务器的响应结果;而Gson用来处理json格式的字符串数据;Jsoup可用来处理html格式的内容。

分析

爬虫从来不是一上来就写代码的,最重要的是分析请求,如何获取到有效的信息,而最后才是写代码,只要爬取的思路理清楚后,代码是很容易完成的。

第一步,打开百度搜索关键字历史上的今天

(注:图片无法显示)

第二步,我们要看浏览器如何请求到“历史上的今天”这些数据的,按F12打开Network面板,然后刷新浏览器,查看请求。

发现通过如下的URL即可请求到“历史上的今天”的页面内容,返回的是html源码内容。

Request URL: https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%8E%86%E5%8F%B2%E4%B8%8A%E7%9A%84%E4%BB%8A%E5%A4%A9&fenlei=256&rsv_pq=a2dbc7d900047768&rsv_t=0c6ckpvpgFs4uKd8Xon5m%2FKW%2B4EZcnObkZ4N4A%2BBwxZNXkHgcrSoxlVwj20&rqlang=cn&rsv_enter=1&rsv_dl=ib&rsv_sug3=15&rsv_sug1=16&rsv_sug7=101
Request Method: GET
Status Code: 200 OK

也就是说我们要寻找的数据就在请求响应回的html源码内容中,但源码内容太多了,眼睛很难以找到,所以我们在Response面板的html源码内容中搜索上面显示的历史上的今天的关键字,例如搜索关键字"德国著名飞行员"。

发现共匹配到4个,在Response面板中查看html源码感觉还是不太方便,在页面按鼠标右键查看页面源码。
发现搜索到的结果有两种情况:

  • 第一种,结果隐藏在html注释中的json字符串中。
  • 第二种,结果在html标签中,需要提取。
    发现json字符串中的数据更加完整,更加方便提取。
    我们先把这段json格式的字符串复制到JSON可视化网站上查看。
    打开"视图"选项卡,以树形视图查看

其中date字段表示今天的日期,而cardList则是“历史上的今天”所有事件。cardList是一个数组,数组中每一项都是一个对象,cardList.yearTag表示事件的年份,cardList.url则是该事件的百度百科链接,cardList.titleTip是该事件的完整标题名称,cardList.title是标题简称,cardList.textTip是该事件的完整内容,cardList.text是事件内容摘要,cardList.image是该事件的图像。

我们发现上面的请求URL的参数太多了,我们可以尝试减少一些无用的参数,最后得到更加简洁的URL:

Request URL: https://www.baidu.com/s?wd=历史上的今天
Request Method: GET
Status Code: 200 OK

从上面的分析我们已经能得到我们需要的数据了,步骤如下:

  • 第一步,发送GET请求,注意携带请求头,响应返回html页面内容。
  • 第二步,从html页面内容中提取出藏有关键数据的json字符串。
  • 第三步,从json字符串中解析出我们需要的数据。

代码

通过上面的分析,我们很容易就可以写出代码。

注意,上面的分析跟编程语言,爬虫既可以用python写,也可以用Java来写。而我这里提供的仅仅是Java代码,当然也可以根据上面的分析写一份python代码。

代码如下:

public class Crawler {
    public static void main(String[] args) {
        // 第一步,拼接URL
        String url = "https://www.baidu.com/s?ie=UTF-8&wd=历史上的今天";
        // 设置请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36");

        // 第二步,发送请求,获取响应,响应内容为html源码内容
        String htmlContent = HttpRequest.get(url).headerMap(headers, true).execute().body();

        // 第三步,提取html源码中的有效信息,是json字符串隐藏在注释中
        int beginIndex = htmlContent.indexOf("<!--s-data:") + 11;
        int endIndex = htmlContent.indexOf("true}-->") + 5;
        String jsonContent = htmlContent.substring(beginIndex, endIndex);

        // 第四步,使用Gson解析json字符串
        Gson gson = new Gson();
        JsonObject jsonObject = gson.fromJson(jsonContent, JsonObject.class);
        String today = jsonObject.get("date").getAsString();
        JsonArray cardList = jsonObject.get("cardList").getAsJsonArray();
        if (!cardList.isJsonNull() && cardList.size() > 0) {
            for (JsonElement jsonElement : cardList) {
                // 提取json字符串中的有效信息
                JsonObject card = jsonElement.getAsJsonObject();
                String yearTag = card.get("yearTag").getAsString();
                String baikeUrl = card.get("url").getAsString();
                String title = card.get("title").getAsString();
                String textTip = card.get("textTip").getAsString();
                String text = card.get("text").getAsString();
                String image = card.get("image").getAsString();
                System.out.println(yearTag + "\\t\\t" + baikeUrl + "\\t\\t" + title + "\\t\\t" + textTip + "\\t\\t" + text + "\\t\\t" + image);
            }
        }
    }
}

打印结果如下:

1999年		https://baike.baidu.com/item/%E8%B5%96%E8%8E%8E%C2%B7%E6%88%88%E5%B0%94%E5%B7%B4%E4%B9%94%E5%A8%83?fr=luckinsearch		前苏联领袖的妻子赖莎·戈尔...		赖莎·戈尔巴乔娃(Раи́са Макси́мовна Горбачёва,又译雷莎·戈巴卓娃,本姓Титаре́нко,19		赖莎·戈尔巴乔娃(Раи́са Макси́мовна Гор...		https://bkimg.cdn.bcebos.com/smart/377adab44aed2e73e840188a8501a18b86d6faef-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1993年		https://baike.baidu.com/item/%E5%9F%83%E9%87%8C%E5%B8%8C%C2%B7%E5%93%88%E7%89%B9%E6%9B%BC?fr=luckinsearch		德国著名飞行员埃里希·哈特...		埃里希·哈特曼(Erich·Hartmann)是一位纳粹德国空军的头号王牌飞行员。这位前德国空军战斗机飞行员在第二次世界大战中以352架		埃里希·哈特曼(Erich·Hartmann)是一位纳粹德国空军的头号王...		https://bkimg.cdn.bcebos.com/smart/d52a2834349b033b8965b76e10ce36d3d439bd91-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1964年		https://baike.baidu.com/item/%E5%BC%A0%E6%9B%BC%E7%8E%89?fr=luckinsearch		香港电影演员张曼玉出生		张曼玉(Maggie Cheung1964920日—) ,生于香港,祖籍上海,国家一级演员,爱丁堡大学荣誉博士,联合国儿童基金会中国大使。张曼玉是迄今华语影坛获奖最多的电影演员,奖项涵盖十余个国际影展。		张曼玉(Maggie Cheung1964920日—) ,生于香港,祖籍...		https://bkimg.cdn.bcebos.com/smart/42a98226cffc1e178a82206505dae103738da9774306-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1957年		https://baike.baidu.com/item/%E8%AE%A9%C2%B7%E8%A5%BF%E8%B4%9D%E6%9F%B3%E6%96%AF?fr=luckinsearch		芬兰著名作曲家让·西贝柳斯...		让·西贝柳斯是芬兰作曲家。他的著名作品《芬兰颂》曾因沙俄禁演而改名《即兴曲》,芬兰独立后才以《芬兰颂》命名。他一生创作了100多部作品,为芬兰音乐开拓了一个新的时代。		让·西贝柳斯是芬兰作曲家。他的著名作品《芬兰颂》曾因沙俄禁...		https://bkimg.cdn.bcebos.com/smart/91529822720e0cf3a35fc68d0546f21fbe09aa18-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1950年		https://baike.baidu.com/item/%E4%B8%AD%E5%8D%8E%E4%BA%BA%E6%B0%91%E5%85%B1%E5%92%8C%E5%9B%BD%E5%9B%BD%E5%BE%BD?fr=luckinsearch		中华人民共和国国徽图案正...		中华人民共和国国徽(英语:National Emblem of the People's Republic of China)是中华人民共和国主权的象征和标志。国徽		中华人民共和国国徽(英语:National Emblem of the People's...		https://bkimg.cdn.bcebos.com/smart/50da81cb39dbb6fd52666d670c6fbc18972bd4079915-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1946年		https://baike.baidu.com/item/%E6%88%9B%E7%BA%B3%E5%9B%BD%E9%99%85%E7%94%B5%E5%BD%B1%E8%8A%82?fr=luckinsearch		首届戛纳国际电影节在法国...		戛纳国际电影节(英文:Cannes International Film Festival,法文:Festival De Cannes),亦译作康城(坎城)国际电影节,创		戛纳国际电影节(英文:Cannes International Film Festival...		https://bkimg.cdn.bcebos.com/smart/9e3df8dcd100baa1cd1184a9f259ae12c8fcc3ce80c5-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1945年		https://baike.baidu.com/item/%E8%8C%83%E5%BE%90%E4%B8%BD%E6%B3%B0?fr=luckinsearch		香港政治人物范徐丽泰出生		范徐丽泰  (1945920日-),本名徐丽泰,香港建制派政治人物,现任港区全国人大代表及常务委员会成员,范徐丽泰早年在香港		范徐丽泰  (1945920日-),本名徐丽泰,香港建制派政治...		https://bkimg.cdn.bcebos.com/smart/810a19d8bc3eb1351f3efb67af1ea8d3fc1f4474-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1940年		https://baike.baidu.com/item/%E9%BA%BB%E7%94%9F%E5%A4%AA%E9%83%8E?fr=luckinsearch		日本政治家麻生太郎出生		麻生太郎(1940920-),日本政治家和企业家。出身政治世家,思想意识保守,不识民间疾苦,历史认识模糊,而个性张扬、口		麻生太郎(1940920-),日本政治家和企业家。出身政治世...		https://bkimg.cdn.bcebos.com/smart/03087bf40ad162d9f2d3bb483195beec8a1363276706-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1936年		https://baike.baidu.com/item/%E7%8E%8B%E4%BA%9A%E6%A8%B5?fr=luckinsearch		被国民党特务刺杀的王亚樵逝世		王亚樵(18891936),字九光,抗日志士,民族英雄。1889年出生于安徽合肥,自幼读书,聪颖过人,少年时期目睹官吏豪强压榨人		王亚樵(18891936),字九光,抗日志士,民族英雄。1889年出...		https://bkimg.cdn.bcebos.com/smart/35a85edf8db1cb1380a9c5b9d754564e93584b5c-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1911年		https://baike.baidu.com/item/%E8%B5%AB%E5%BE%B7?fr=luckinsearch		近代英国侵华代表人物赫德逝世		赫德,英国人,28岁担任大清海关总税务司,掌权长达45年,被清廷视为客卿,在衰朽的旧帝国制度中创造出唯一廉洁不贪腐的高效衙		赫德,英国人,28岁担任大清海关总税务司,掌权长达45年,被清...		https://bkimg.cdn.bcebos.com/smart/5bafa40f4bfbfbed410b0a9578f0f736aec31f8d-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1899年		https://baike.baidu.com/item/%E5%88%97%E5%A5%A5%C2%B7%E6%96%BD%E7%89%B9%E5%8A%B3%E6%96%AF?fr=luckinsearch		德裔美国政治哲学家列奥·施...		列奥·施特劳斯(Leo Strauss)是一个争议且传奇的人物。列奥·施特劳斯(Leo Strauss)是一位神秘的政治哲学家。在里根、老布什		列奥·施特劳斯(Leo Strauss)是一个争议且传奇的人物。列奥·...		https://bkimg.cdn.bcebos.com/smart/34fae6cd7b899e511fc8c2aa4aa7d933c9950dcd-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1870年		https://baike.baidu.com/item/%E6%99%AE%E6%B3%95%E6%88%98%E4%BA%89?fr=luckinsearch		普法战争,普鲁士军包围巴黎		18701871年普鲁士同法国之间的战争。因争夺欧洲大陆霸权和德意志统一问题,普法两国之间关系长期紧张。1870714日,俾斯麦		18701871年普鲁士同法国之间的战争。因争夺欧洲大陆霸权和德...		https://bkimg.cdn.bcebos.com/smart/a044ad345982b2b7d0a2e36356e1dcef76094b362d4d-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1863年		https://baike.baidu.com/item/%E5%8D%97%E5%8C%97%E6%88%98%E4%BA%89?fr=luckinsearch		南北战争的奇卡牟加战役结束		南北战争(American Civil War)即美国内战,是美国历史上唯一一次内战,参战双方为北方美利坚合众国和南方的美利坚联盟国。战		南北战争(American Civil War)即美国内战,是美国历史上唯一...		https://bkimg.cdn.bcebos.com/smart/0ff41bd5ad6eddc451dac9904f97a1fd5266d016950e-bkimg-process,v_1,rw_1,rh_1,maxl_800,pad_1?x-bce-process=image/resize,m_fill,w_128,h_128,align_0,limit_0
1842年		https://baike.baidu.com/item/%E8%A9%B9%E5%A7%86%E6%96%AF%C2%B7%E6%9D%9C%E7%93%A6?fr=luckinsearch		杜瓦瓶发明人詹姆斯·杜瓦出生		詹姆斯·杜瓦爵士(Sir James Dewar)(1842920-1923327日)苏格兰物理学家,化学家,发明家。		詹姆斯·杜瓦爵士(历史上的今天:数据库之父逝世;苹果公司购买 CUPS 代码;IBM 芯片联盟

JAVA爬虫实践(实践三:爬虫框架webMagic和csdnBlog爬虫)

手机之父出生 | 历史上的今天

AlphaGo 成名之战 | 历史上的今天

历史上的今天8月19日:大型计算机先驱和小型机之父诞生;中国雅虎邮箱成历史...

历史上的今天8月19日:大型计算机先驱和小型机之父诞生;中国雅虎邮箱成历史...