Java爬虫的使用案例及简单总结

通过三个简单的案例,来实现的,都是不加验证的情况下. 如果有拼图验证网上也有对应的实现方法自行查找即可. 这里仅仅是一个简单的Demo, 练习使用

0. 爬取网站的配置:
article:
  config:
    #中央新闻网-三农头条数据部分
    ntvUrl: https://www.ntv.cn/
    # 全国农技推广网- 农技动态部分
    nongJi: https://www.natesc.org.cn/dtxx/index?CategoryId=959cd01c-e9fa-43d9-a04b-48317bdc3794
    # 农技网基础路径
    nongJiBaseUrl: https://www.natesc.org.cn
    # 中国农网-热点推荐数据
    farmerUrl: https://www.farmer.com.cn/
1. 依赖导入

<dependency>
    <groupId>org.jsoupgroupId>
    <artifactId>jsoupartifactId>
    <version>1.13.1version>
dependency>

<dependency>
    <groupId>net.sourceforge.htmlunitgroupId>
    <artifactId>htmlunitartifactId>
    <version>2.43.0version>
dependency>

<dependency>
    <groupId>commons-iogroupId>
    <artifactId>commons-ioartifactId>
    <version>2.11.0version>
dependency>
2. 配置类
package com.saas.prod.common;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author : Cookie
 * date : 2023/11/15
 */
@Component
@Data
// prefix 中的配置只能是小写,否则编译过不去好像
@ConfigurationProperties(prefix = "article.config")
public class ArticleMessageConfig {

    /**
     * 中央新闻网 三农头条数据url
     */
    private String ntvUrl;

    /**
     * 农技中心动态
     */
    private String nongJi;

    /**
     * 农技基础url
     */
    private String nongJiBaseUrl;

    /**
     * 中国农网url
     */
    private String farmerUrl;
}

中央新闻网-三农动态部分
@Override
    public void insertNtvData() {
        String url = messageConfig.getNtvUrl();
        String html = HttpClientUtil.doGetForHTML(url);
        Document document = Jsoup.parse(html);
        Elements elements = document.getElementsByClass("question_rank");
        Elements aElements = elements.get(0).select("a");
        for (Element aElement : aElements) {
            String href = aElement.attr("href");
            String title = aElement.getElementsByTag("p").attr("title");
            ArticleMessage build = ArticleMessage.builder()
                    .title(title)
                    .insertTime(LocalDateTime.now())
                    .build();
            if (getHref(href, build))
                break;
        }
    }

    /**
     * 三农头条数据填充
     *
     * @param url   路径
     * @param build 对象
     */
    private boolean getHref(String url, ArticleMessage build) {
        String html = HttpClientUtil.doGetForHTML(url);
        Document document = Jsoup.parse(html);
        Elements article = document.select("div.art_con");
        Elements select = document.select("p.mb10");
        String source = select.select("span").get(0).text();
        String createTime = select.select("span").get(1).text();
        build.setSource(source);
        build.setTime(createTime.split(" ")[0]);
        build.setArticle(article.toString().replace("
", "
")); String todayStartStr = getTodayStartStr(); // 如果是当天的新闻再插入到数据库,因为旧数据都已经插入了也就没有必要执行了 if (todayStartStr.compareTo(build.getTime()) <= 0) { if (0 == articleMessageMapper.selectByTitle(build.getTitle())) articleMessageMapper.insert(build); } else { // 说明剩余的数据都是旧数据,就不在操作直接返回 return true; } return false; }
中国农网-热点推荐数据
@Override
    public void insertFarmerData() {
        Document parse = Jsoup.parse(HttpClientUtil.doGetForHTML(messageConfig.getFarmerUrl()));
        Elements elements = parse.getElementsByClass("area-center w-486");
        Elements a = elements.select("a");
        for (Element element : a) {
            String href = element.attr("href");
            String title = element.text();
            ArticleMessage build = ArticleMessage.builder()
                    .title(title)
                    .build();
            if (setMessageForFarmer(href, build))
                break;
        }
    }

/**
     * 中国农网获取数据填充
     *
     * @param href  链接
     * @param build 数据对象
     */
    private boolean setMessageForFarmer(String href, ArticleMessage build) {
        try {
            Document parse = Jsoup.parse(HttpClientUtil.doGetForHTML(href));
            Elements elementsByClass = parse.getElementsByClass("index-introduce");
            Elements elements = elementsByClass.select("li");
            String source = elements.first().select("span").text();
            String date = elementsByClass.select("ul").first().select("div").first().select("span").text();

            Elements article = parse.getElementsByClass("textList");
            build.setSource(source);
            build.setTime(date.split(" ")[0]);
            build.setInsertTime(LocalDateTime.now());
            build.setArticle(article.toString().replace("
", "
")); String todayStartStr = getTodayStartStr(); // 如果是当天的新闻再插入到数据库,因为旧数据都已经插入了也就没有必要执行了 if (todayStartStr.compareTo(build.getTime()) <= 0) { if (0 == articleMessageMapper.selectByTitle(build.getTitle())) articleMessageMapper.insert(build); } else { return true; } } catch (Exception e) { // 这里有异常的及时提醒我查找问题 MailUtils.sendMail("[email protected]", "数据插入异常", "路径:" + href); log.error("数据插入异常:{},路径{}", e.getMessage(), href); return true; } return false; }
全国农技推广网- 农技动态部分
    @Override
    public void insertNongJiData() {
        Document document1 = getParsedDocument(messageConfig.getNongJi());
        if (document1 == null)
            return;
        Element newsUl = document1.getElementById("newsUl");
        Elements elements = newsUl.select("a");
        for (Element element : elements) {
            String href = element.attr("href");
            String title = element.attr("title");
            String finalUrl = messageConfig.getNongJiBaseUrl() + href;
            ArticleMessage build = ArticleMessage.builder()
                    .title(title)
                    .build();
            // 填充其他数据
            if (setMessageForNongji(build, finalUrl))
                break;
        }
    }

    /**
     * 填充农技动态中心数据
     *
     * @param build    对象
     * @param finalUrl 路径
     */
    private boolean setMessageForNongji(ArticleMessage build, String finalUrl) {
        try {
            Document parsedDocument = getParsedDocument(finalUrl);
            if (parsedDocument == null)
                return true;
            Element newsTime = parsedDocument.getElementById("newsTime");
            Elements elements = newsTime.getElementsByClass("span1");
            String date = elements.first().getElementsByClass("span2").text();
            String source = elements.get(1).getElementsByClass("span2").text();
            Element content = parsedDocument.getElementById("content");
            String finalContent = content.toString().replace("src=\"", "src=\"" + messageConfig.getNongJiBaseUrl());
            build.setTime(date);
            build.setSource(source);
            build.setInsertTime(LocalDateTime.now());
            // 填充文本数据包括图片
            build.setArticle(finalContent);
            String todayStartStr = getTodayStartStr();
            // 插入当天的
            if (todayStartStr.compareTo(date) <= 0) {
                if (0 == articleMessageMapper.selectByTitle(build.getTitle()))
                    articleMessageMapper.insert(build);
            } else {
                // 说明剩余的数据都是旧数据,就不在操作直接返回
                return true;
            }
        } catch (Exception e) {
            MailUtils.sendMail("[email protected]", "数据插入异常", "路径:" + finalUrl);
            log.error("数据插入异常:{},路径{}", e.getMessage(), finalUrl);
        }
        return false;
    }
示例HTML:
<div class="index-introduce">
  <ul>
    <li>来源:
      <span>中国农网span>
    li>
    <li>编辑:
      <span>暴佳然span>
    li>
    <li>作者:
      <span>杨志华span>
    li>
    <div>
      <span>2023-11-17 08:45:11span>
    div>
  ul>
  <div class="fontSize">
    <img class="add" src="https://www.farmer.com.cn//Public/newNongWang/images/字体变大.png?time=657" alt="">
    <img class="sub" src="https://www.farmer.com.cn//Public/newNongWang/images/字体减小.png?time=277" alt="">
  div>
div>
Document parse = Jsoup.parse(HttpClientUtil.doGetForHTML(href));
// 通过class获取节点
Elements elementsByClass = parse.getElementsByClass("index-introduce");
// 获取节点中所有的li标签数据
Elements elements = elementsByClass.select("li");
// 获取第一个li中的span标签中的文本内容  也就是这里的: 中国农网
String source = elements.first().select("span").text();
// 获取ul标签,再获取ul中的div获取span中的文本
String date = elementsByClass.select("ul").first().select("div").first().select("span").text();

方法总结:

获取标签的常用方法
getElementsByClass
// 通过class定位
Elements elementsByClass = parse.getElementsByClass("index-introduce");
getElementsById
// 通过id定位
Element newsTime = parsedDocument.getElementById("newsTime");
select

这里方法有很多选择方式,详细在最下面的链接中

通过Element对象获取对应的标签

getElementsByTag

通过标签获取

String title = aElement.getElementsByTag("p").attr("title");
获取属性常用方法
attr
String href = element.attr("href");
String title = element.attr("title");
总结:
  1. 通过HttpClient获取到界面的html
  2. 通过JSoup进行解析, 获得一个Document对象
  3. 通过方法一层一层的获取到其中的数据,或者属性

其他的常用方法链接:

jsoup使用指南

你可能感兴趣的:(项目中的笔记,爬虫,java,Jsoup)