前几天有人找到我问会不会写爬虫,我说简单的可以,复杂的就没有办法了。
结果丢给我一个报名网站,要实时获取对方网站不同地区部门职位的报名情况,所以就尝试了一下。
效果还可以,代码如下:
需要的依赖:

pom.xml

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.16.1</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.39</version>
        </dependency>


具体代码:
RobotServer

package com.demo.server;


import com.alibaba.fastjson2.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author zf
 * @ClassName RobotServer.java
 * @ProjectName demo
 */
@Service
public class RobotServer {

    // 目标网站信息
    static String host = "";
    static String path = "";
    static String url = host + path;

    static String updateTime = "null";

    public JSONObject queryData(String areaCode) {

        ArrayList<Object> list = new ArrayList<>();

        try {

            // 使用Jsoup发送GET请求获取网页内容
            Document document = Jsoup.connect(url).get();
            // 获取form表单元素
            Element formElement = document.selectFirst("form");
            // 获取职位所属地区选择框元素
            Element jobAreaListElement = formElement.selectFirst("select[name=jobAreaList]");

            // 模拟表单提交
            formElement.selectFirst("input[type=submit]").attr("value", "查询");
            formElement.selectFirst("select[name=jobAreaList] option[value=" + areaCode + "]")
                    .attr("selected", "selected"); //选中指定的职位所属地区

            // 修改提交URL地址
            url = url.replace(path, formElement.attr("action"));

            // 发送POST请求并获取结果
            document = Jsoup.connect(url).data(jobAreaListElement.attr("name"), areaCode).post();

            // 获取更新时间
            updateTime = extractTime(document.select("span").first().text());

            // 获取所有满足条件的table
            Elements tables = document.select("table.tableline");

            // 获取第3个table
            Element thirdTable = tables.get(2);

            // 获取表格的所有行
            Elements rows = thirdTable.select("tr");

            // 遍历每一行,跳过表头
            for (int i = 1; i < rows.size(); i++) {
                Element row = rows.get(i);

                // 获取每一行的列
                Elements cols = row.select("td");

                // 获取部门名称
                String department = cols.get(0).text();
                // 获取职位名称
                String position = cols.get(1).text();
                // 获取开考比例
                String examRatio = cols.get(2).text();
                // 获取招考人数
                String recruitCount = cols.get(3).text();
                // 获取报名成功人数
                String cellStyle = cols.get(4).attr("style"); //获取单元格的style属性
                // 实际报名人数
                String application = getApplication(cellStyle);

                // 具体报考数据
                JSONObject obj = new JSONObject();
                obj.put("department", department); //部门名称
                obj.put("position", position); //职位名称
                obj.put("examRatio", examRatio); //开考比例
                obj.put("recruitCount", recruitCount); //招考人数
                obj.put("application", application); //报名成功人数
                list.add(obj);
            }
        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
        }

        // 返回数据
        JSONObject object = new JSONObject();
        object.put("updateTime", updateTime);
        object.put("list", list);
        return object;
    }


    // 格式化报名人数
    private String getApplication(String cellStyle) {
        // 默认报名人数
        String application = "null";
        // 判断cellStyle是否包含特定选项
        String[] colors = {"DodgerBlue", "Yellow", "Red"}; //颜色集合
        String[] ranges = {"0-2", "3-50", "51+"}; //对应的区间集合

        boolean hasColor = false; //初始化标志变量,用于判断是否存在特定颜色

        for (String color : colors) { //遍历所有颜色
            if (cellStyle.contains(color)) { //如果cellStyle包含颜色
                hasColor = true; //设置标志变量为true
                break;
            }
        }
        if (hasColor) { //如果存在特定颜色
            for (int c = 0; c < colors.length; c++) { //遍历颜色集合
                if (cellStyle.contains(colors[c])) { //如果cellStyle包含当前颜色
                    application = ranges[c]; //设置对应的区间值
                    break;
                }
            }
        }
        return application;
    }

    // 格式化时间
    public static String extractTime(String input) {
        String pattern = "(\\d{4}/\\d{1,2}/\\d{1,2} \\d{1,2}:\\d{2}:\\d{2})";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(input);
        if (m.find()) {
            String rawTime = m.group(1);
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                Date date = inputFormat.parse(rawTime);
                return outputFormat.format(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return "null";
    }

}

最后修改:2023 年 11 月 16 日
给我一点小钱钱也很高兴啦!o(* ̄▽ ̄*)ブ