SpringBoot任务——JSoup+定时任务 定时爬取微博热搜至数据库

SpringBoot任务——JSoup+定时任务 定时爬取微博热搜至数据库

0.前言

截至本文写完:

  • 微博热搜的网址为:https://s.weibo.com/top/summary 如有变化,自行百度微博热搜。
  • HTML源码中,热搜数据在table标签中,而且第一个置顶的热搜没有热度。有时候还有推荐(应该是广告)
  • 刷新后可能会有不同结果,几率还挺大,我也是服了。

如下图所示:

在这里插入图片描述

1.导入JSoup依赖

        <!--   jsoup HTML解析库     -->
        <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.13.1</version>
        </dependency>

2.测试爬取微博热搜

微博热搜的网址: https://s.weibo.com/top/summary

Ctrl+U查看HTML源码,可知热搜数据以table显示,Jsoup爬取table标签中的内容,搜索一下便可…

我是参考这篇博客:[Java jsoup table 中获取td和tr]( http://www.yq1012.com/myweb/2162.html )

由此可知爬取table标签中的内容还是很简单的,在测试类中试试,代码加注释如下:

    @Test
    void TestCrawlingHotSearch() {
        try {
            String urlStr = "https://s.weibo.com/top/summary";
            final Document doc = Jsoup.connect(urlStr).get();//获取html
            Elements trs = doc.select("tbody").select("tr");//获取tbody下的所有tr下的html内容
            for (org.jsoup.nodes.Element tr : trs) {
                Elements tds = tr.select("td");
                String rank = tds.get(0).text();//排名
                String num = tds.get(1).select("span").text();//热度指数
                String title = tds.get(1).select("a").text();//热搜标题
                String url = tds.get(1).select("a").attr("href");//热搜URL网址(相对地址)
                String baseurl = "https://s.weibo.com";//和上述url组成完整可访问的单个热搜URL
                //以 排名+热搜标题+热搜指数+有效URL的形式输出
                System.out.println(rank + " " + title + " " + num + " " + baseurl + url);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

测试结果如下:2020.03.02 21点44分爬取的微博热搜:热搜榜上只有50条,最上面的是置顶的,没有热搜指数。接下来的定时任务中把这个去掉,那个for循环从1开始即可。

28个省份恢复省际省内道路客运  https://s.weibo.com/weibo?q=%2328%E4%B8%AA%E7%9C%81%E4%BB%BD%E6%81%A2%E5%A4%8D%E7%9C%81%E9%99%85%E7%9C%81%E5%86%85%E9%81%93%E8%B7%AF%E5%AE%A2%E8%BF%90%23&Refer=new_time
1 孙杨公布完整血样瓶 6140146 https://s.weibo.com/weibo?q=%23%E5%AD%99%E6%9D%A8%E5%85%AC%E5%B8%83%E5%AE%8C%E6%95%B4%E8%A1%80%E6%A0%B7%E7%93%B6%23&Refer=top
2 高鑫去口罩厂做义工 3514533 https://s.weibo.com/weibo?q=%23%E9%AB%98%E9%91%AB%E5%8E%BB%E5%8F%A3%E7%BD%A9%E5%8E%82%E5%81%9A%E4%B9%89%E5%B7%A5%23&Refer=top
3 韩国新冠肺炎定点医院16名护士辞职 2636260 https://s.weibo.com/weibo?q=%23%E9%9F%A9%E5%9B%BD%E6%96%B0%E5%86%A0%E8%82%BA%E7%82%8E%E5%AE%9A%E7%82%B9%E5%8C%BB%E9%99%A216%E5%90%8D%E6%8A%A4%E5%A3%AB%E8%BE%9E%E8%81%8C%23&Refer=top
4 余文乐 2355872 https://s.weibo.com/weibo?q=%E4%BD%99%E6%96%87%E4%B9%90&Refer=top
5 偶像失声 2011436 https://s.weibo.com/weibo?q=%E5%81%B6%E5%83%8F%E5%A4%B1%E5%A3%B0&Refer=top
6 马云回赠日本100万只口罩 1627005 https://s.weibo.com/weibo?q=%23%E9%A9%AC%E4%BA%91%E5%9B%9E%E8%B5%A0%E6%97%A5%E6%9C%AC100%E4%B8%87%E5%8F%AA%E5%8F%A3%E7%BD%A9%23&Refer=top
....

其实关于热搜的爬取到这就没了,后面其实就是加了springboot中的定时任务和MybatisPlus实现了定时爬取热搜至数据库。
关于定时任务和MybatisPlus简单整合可查看:
SpringBoot任务——定时任务
SpringBoot数据访问——整合MybatisPlus

3. 配合定时任务注解实现定时爬取至数据库

3.1 导入依赖与配置MySQL

这里用到了lombok插件+MybatisPlus+MySQL,导入相关依赖:

        <!--        MySQL驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--        Lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--        mybatis-plus 启动器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>

在application.proterties或者新建一个application.yml配置文件,配置MySQL数据源:

默认的application.proterties

#mysql数据源配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://*.*.*.*:3306/数据库名称
spring.datasource.username=账号
spring.datasource.password=密码

yml格式:

#mysql数据源配置
spring:
  datasource:
    username: 账号
    password: 密码
    url: jdbc:mysql://*.*.*.*:3306/数据库名称
    driver-class-name: com.mysql.jdbc.Driver
3.2 热搜实体类与对应的数据表

简单方便起见,这里都用了字符串类型…我太懒了

实体类:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//id 时间 排名 热搜标题 热搜指数 有效URL
@Data
@AllArgsConstructor
@NoArgsConstructor
public class HotSearch {
    String id;//UUID生成
    String date;//时间格式:yyyy-MM-dd HH:mm:ss
    String rank;
    String title;
    String number;
    String url;
}

数据表:
数据表

3.3 使用MyBatisPlus写实体类对应的Mapper

使其具备基本的CRUD功能。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.piao.springboot_scheduled_jsoup.Entity.HotSearch;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface HotSearchMapper extends BaseMapper<HotSearch> {
}

3.4 @Scheduled注解实现定时执行爬取

在之前的基础上加了时间和ID,通过hotSearchMapper将数据插入数据当中。

@Service
public class MyJSoupService {
    @Resource
    HotSearchMapper hotSearchMapper;

    //定时爬取微博热搜 每天中午12点爬
    @Scheduled(cron ="0 50 22 * * *")
    public void CrawlingHotSearch() {
        try {
            String urlStr = "https://s.weibo.com/top/summary";
            final Document doc = Jsoup.connect(urlStr).get();
            Elements trs = doc.select("tbody").select("tr");
            for (int i = 1; i < trs.size(); i++) {
                Elements tds = trs.get(i).select("td");
                String rank = tds.get(0).text();//排名
                String num = tds.get(1).select("span").text();//热度指数
                String title = tds.get(1).select("a").text();//标题
                String url = tds.get(1).select("a").attr("href");//热搜详细(标题+热度)
                String baseurl="https://s.weibo.com";//基址
                //时间
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
                String date = df.format(new Date());// new Date()为获取当前系统时间,也可使用当前时间戳
                //id
                String hotSearchId= UUID.randomUUID()+"";
                //以 id+时间+排名+热搜标题+热搜指数+有效URL的形式输出
                System.out.println("id:"+hotSearchId+" 时间"+date+" 排名"+rank+" 标题"+title+" 热搜指数"+num+" 有效URL"+baseurl+url);
                hotSearchMapper.insert(new HotSearch(hotSearchId,date,rank,title,num,baseurl+url));//插入单条热搜数据
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
3.5 @EnableScheduling注解开启定时任务

别忘了使用@EnableScheduling注解标注在类上开启定时任务,这里标注在的启动类上:

@EnableScheduling
@SpringBootApplication
@MapperScan("com.piao.springboot_scheduled_jsoup.mapper")
public class SpringbootScheduledJsoupApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootScheduledJsoupApplication.class, args);
    }

}

3.6 运行走起

我测试把时间调为22.52执行了,结果如下:

控制台正常输出:

控制台正常输出

数据库正常写入50条热搜数据:

数据库正常写入50条热搜数据

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值