您的位置:首页 > 编程语言 > Java开发

java爬虫jsoup,实现通过csdn专栏地址爬取csdn专栏每篇文章的标题和地址

2020-05-11 04:06 1791 查看

程序猿学社的GitHub,欢迎Star
github技术专题
本文已记录到github

文章目录

  • 实战
  • 分析
  • 结论
  • 前言

    从19年开始,社长,就在写系列文章,整个系列写完后,就需要写一篇总结的文章,需要把所有的文章归纳进去。相信不少童鞋都会有这种困惑。

    需求

    通过csdn系列文章的网站,采用jsoup,输出该系列文章的所有标题和url地址。使用MD方式网址输出

    要求

    • 需要有一定的css、html、js前端基础
    • 有一定的java基础

    api接口文档

    查找元素

    方法 描述
    getElementById(String id) 根据id选择器获取Element
    getElementsByTag(String tagName) 通过标签过滤获取Element
    getElementsByClass(String className) 通过类样式选择器获取Element
    getElementsByAttribute(String key) 通过属性名获取Element

    获取元素的值

    方法 描述
    attr(String attributeKey) 获取属性的值
    attr(String attributeKey, String attributeValue) 给属性赋值
    text() 获取对应的值,只是单纯的值
    html() 获取对应的html值,包含标签

    实战

    pom.xml

    <!--爬取数据关键jsoup -->
    <dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.3</version>
    </dependency>
    • 导入jsoup依赖

    代码

    package com.cxyxs.jsoup.util;
    
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.net.URL;
    
    /**
    * Description:测试
    * Author: 程序猿学社
    * Date:  2020/5/10 18:07
    * Modified By:
    */
    public class JsoupUtils {
    public static void main(String[] args) throws  Exception {
    getList("https://blog.csdn.net/qq_16855077/category_9722768.html");
    }
    
    /**
    * 通过csdn的系列文章网址输出对应的内容
    * @param url
    * @throws Exception
    */
    public static void getList(String url)throws  Exception{
    //网址
    Document document = Jsoup.connect(url).get();
    // 获取标题
    //String title = document.title();
    //获取头部信息
    //Element head = document.head();
    //取到菜单列表ul
    Elements elements = document.getElementsByClass("column_article_list");//取出每个li
    Elements elementsByTag = elements.get(0).getElementsByTag("li");
    for (Element el : elementsByTag) {
    //取出每个li元素的href
    String href = el.getElementsByTag("a").attr("href");
    //先取出h2标签
    String titleDiv = el.getElementsByTag("h2").text();
    String[] titles = titleDiv.split(" ");
    System.out.println("!["+titles[1]+"]("+href+")");
    }
    }
    }


    到这里,我们就实现了通过csdn列表的网址,输出markdown的列表的内容格式。是不是感觉很so easy哦?

    • 也有不少人通过httpclient方法实现,当然,通过这种方法也可以实现。说说实现的大致思路。首先通过网址获取整个html,而且通过自己各种写判断处理,因太麻烦,不建议采用这种方式

    看到这里是不是一脸懵逼?别急,我们一步一步的分析一下社长的代码,为什么要这样编写

    分析

    第一步

    Document document = Jsoup.connect(url).get();
    • 这里的document,我们通过syso输出,可以知道实际上,就是把url对应网址输出。等同于,我们在网页输入F12,进入开发者调试模式
    • 输出的内容就是整个html页面,也就是红色区域的内容。
    • 到这一步,我们已经实现,取到整个html页面。

    第二步 获取文章列表的ul

    • 点击红色区域的图标,把他移动到,我们我们需要选择的标题这一行上面。
    • 分析csdn前端开发是如何显示文章列表的
    • 通过分析,可以看出,最外层是ul,里面的每一篇文章的显示都是一个li。例如10篇文章,就有10个li。
    //取到菜单列表ul
    Elements elements = document.getElementsByClass("column_article_list");

    这里为什么要调用getElementsByClass方法?

    • ul标签上是class属性,值为column_article_list,通过社长之前的api接口文档,可知,class选择器需要调用getElementsByClass。
    • 到这里,我们已经实现从整个html变为只获取ul的内容。万里长征又进了一步。

    第三步 获取文章的每个li

    //取出每个li
    Elements elementsByTag = elements.select("li");for (Element el : elementsByTag) {
    //取出每个li元素的href
    String href = el.getElementsByTag("a").attr("href");
    //先取出h2标签
    String titleDiv = el.getElementsByTag("h2").text();
    String[] titles = titleDiv.split(" ");
    //![描述](网址)
    System.out.println("!["+titles[1]+"]("+href+")");
    }
    • elements.select(“li”) 获取所有li标签的html元素
      一步一步再来剖析
    Elements elementsByTag = elements.select("li");
    • 在ul中,获取li,实际上返回如下

      分析单个的li,发现只需要取到href对应的属性值,h2标签就可以实现我们的功能。

      获取href的值
    String href = el.getElementsByTag("a").attr("href");
    • getElementsByTag获取a标签这个dom元素
    • attr(“href”)为获取当前dom元素属性为href的值

    获取标题的值

    //先取出h2标签
    String titleDiv = el.getElementsByTag("h2").text();
    String[] titles = titleDiv.split(" ");

    • titles[1] 为文章标题的值
      获取标题的值,为什么要这些写?
      通过查看html代码,发现h2里面有一个span标签,里面的值为文章类型(原创、转载),紧接着就是文字标题。
    • 没有办法,通过标签选择器筛选到标题的值,社长想到的方法,获取h2的text的值,这样我们去到的内容为"原创 [多线程XXX] 十四面试官说:说说java中XXXX"
    • 把这个字符串按空格切割,取索引为1的值,就是我们的标题

    结论

    本文最好有一定的前端基础,不然,看着,会有点懵逼。如果你懂js、css、html,你再去看jsoup提供的api接口,会发现,几乎完全类似。

    本文仅供学习,本文只是读取个人博客专栏的一个地址,获取每个文章的标题和网址,方便专栏文章汇总。如有问题,请联系我删除

    学习源码

    作者:程序猿学社
    原创公众号:『程序猿学社』,专注于java技术栈,分享java各个技术系列专题,以及各个技术点的面试题。
    原创不易,转载请注明来源(注明:来源于公众号:程序猿学社, 作者:程序猿学社)。

    程序猿学社 博客专家 原创文章 294获赞 2467访问量 68万+ 关注 私信
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐