JAVA实现问财爬虫

news2024/11/25 8:14:30

通过 RestTemplate 将查询语句申请发送至问财,实现同花顺问财的爬虫获取数据,例子中实现了将爬取的数据写入excel文件并染成红色,可将其改造放入数据库中.

通过测试发现爬虫自动能访问一百多次左右,会被官方识别为爬虫,解决办法为用浏览器打开问财,验证下图形验证码(因为问财nginx是通过识别ip访问的,短期内同一个ip访问太频繁会被识别出来)

爬取的网站地址为 http://www.iwencai.com/customized/chart/get-robot-data ,爬取过程中会发送请求头和消息体,消息头包含session,这部分是分析网站之后,抽取的js保存到本地,到本地进行运行,得到session后保存在请求头里面进行请求。

需要用到的maven依赖
        <!--执行js脚本依赖-->
        <dependency>
            <groupId>org.openjdk.nashorn</groupId>
            <artifactId>nashorn-core</artifactId>
            <version>15.3</version>
        </dependency>
        
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.11</version>
        </dependency>
部分java代码
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.swing.DesktopUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.lhk.datasql.util.MyUtil;
import org.apache.poi.ss.usermodel.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.File;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;


/**
 * 问财爬虫实现
 */
public class WCTool {

    private static String WC_ROBOT = "http://www.iwencai.com/customized/chart/get-robot-data";
    private static File file = FileUtil.file(MyUtil.DESKTOP_PREFIX + "市场情绪.xlsx");
    private static String[] NumToStr = new String[]{"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
    private static AtomicInteger maxHarden = new AtomicInteger(0);
    private static RestTemplate restTemplate = new RestTemplate();

    public static void main(String[] args) {
        //List<DateTime> dateSubList = MyUtil.getDateSubList("2023-05-30", "2023-06-15");
        //for (DateTime dateTime : dateSubList) {
        //    if (HolidayUtils.isWorkDay(dateTime) && !DateUtil.isWeekend(dateTime)) {
        //        String question = "非ST " + DateUtil.format(dateTime, DatePattern.CHINESE_DATE_PATTERN);
        //        writeExcelSheet1(question, dateTime);
        //        writeExcelSheet2(question, dateTime);
        //    }
        //}
        String question = "非ST 今日";
        writeExcelSheet1(question, DateUtil.date());
        writeExcelSheet2(question, DateUtil.date());
        DesktopUtil.open(file);
        //JSONArray datas = getDatas(question + "1板 概念");
        //Map<String, Integer> res = new HashMap<>();
        //for (int i = 0; i < datas.size(); i++) {
        //    String gls = StrUtil.nullToEmpty(datas.get(i, JSONObject.class).get("所属概念", String.class));
        //    for (String s : gls.split(";")) {
        //        res.put(s, res.containsKey(s) ? res.get(s) + 1 : 1);
        //    }
        //}
        //System.out.println(datas);
    }

    private static void writeExcelSheet1(String question, DateTime date) {
        ExcelReader reader = ExcelUtil.getReader(file, "表格");
        List<Object> heads = reader.read().get(0);
        int rowCount = reader.getRowCount();
        reader.close();
        JSONArray datas = getDatas(question + "1板 行业");
        Map<String, Integer> rds = new HashMap<>();
        for (int i = 0; i < datas.size(); i++) {
            for (String s : datas.get(i, JSONObject.class).get("所属同花顺行业", String.class).split("\\-")) {
                rds.put(s, rds.containsKey(s) ? rds.get(s) + 1 : 1);
            }
        }
        Map<String, Object> res = new LinkedHashMap<>(heads.size());
        res.put("日期", DateUtil.format(date, DatePattern.CHINESE_DATE_PATTERN) + ",星期" + NumToStr[DateUtil.dayOfWeek(date) - 2]);
        StringBuffer rsStr = new StringBuffer();
        MapUtil.sortByValue(rds, true).forEach((k, v) -> {
            if (v > 1) {
                rsStr.append(k + "[" + v + "]");
            }
        });
        res.put("当日热点", rsStr);
        maxHarden.set(0);
        IntStream.range(1, 13).forEach(t -> {
            Integer count = getCount(question + t + "板");
            if (count > 0) {
                maxHarden.set(t);
                res.put(NumToStr[t - 1] + "板", count);
            } else {
                res.put(NumToStr[t - 1] + "板", "");
            }
        });
        ExcelWriter writer = ExcelUtil.getWriter(file, "表格");
        writer.setCurrentRow(rowCount);
        writer.write(Arrays.asList(res));
        sheet1CellStyle(writer, rowCount, res);
        writer.close();
    }

    private static void writeExcelSheet2(String question, DateTime date) {
        ExcelReader reader = ExcelUtil.getReader(file, "折线图");
        List<Object> heads = reader.read().get(0);
        int rowCount = reader.getRowCount();
        reader.close();
        Map<String, Object> res = new LinkedHashMap<>(heads.size());
        res.put("日期", DateUtil.format(date, DatePattern.CHINESE_DATE_PATTERN) + ",星期" + NumToStr[DateUtil.dayOfWeek(date) - 2]);
        for (int i = 1; i < heads.size(); i++) {
            String str = String.valueOf(heads.get(i));
            Integer count = getCount(question + " " + str);
            res.put(str, count);
        }
        /**
         * 单独处理最高板
         */
        res.put("最高板", maxHarden.get());
        ExcelWriter writer = ExcelUtil.getWriter(file, "折线图");
        writer.setCurrentRow(rowCount);
        writer.write(Arrays.asList(res));
        sheet2CellStyle(writer, rowCount, heads.size());
        writer.close();
    }

    private static void sheet1CellStyle(ExcelWriter writer, int rowCount, Map<String, Object> map) {
        Font font = writer.getWorkbook().createFont();
        font.setFontName("楷体");
        font.setFontHeightInPoints((short) 11);
        for (int i = 0; i < 2; i++) {
            setCellStyle(writer, i, rowCount, font, IndexedColors.LIGHT_GREEN);
        }
        for (int i = 0; i < 12; i++) {
            String val = MapUtil.getStr(map, NumToStr[i] + "板");
            if (StrUtil.isNotBlank(val)) {
                setCellStyle(writer, i + 2, rowCount, font, IndexedColors.RED1);
            }
        }
    }

    private static void sheet2CellStyle(ExcelWriter writer, int rowCount, int maxCol) {
        Font font = writer.getWorkbook().createFont();
        font.setFontName("楷体");
        font.setFontHeightInPoints((short) 11);
        for (int i = 0; i < maxCol; i++) {
            setCellStyle(writer, i, rowCount, font, IndexedColors.LIGHT_GREEN);
        }
    }

    private static void setCellStyle(ExcelWriter writer, int row, int col, Font font, IndexedColors colors) {
        CellStyle cellStyle = writer.createCellStyle(row, col);
        cellStyle.setFillForegroundColor(colors.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setFont(font);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setWrapText(true);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
    }

    private static Integer getCount(String question) {
        Integer count = getBodyData(question).get("meta", JSONObject.class)
                .get("extra", JSONObject.class)
                .get("code_count", Integer.class);
        System.out.println(question + "---" + count);
        return count;
    }

    private static JSONArray getDatas(String question) {
        return getBodyData(question).get("datas", JSONArray.class);
    }

    private static JSONObject getBodyData(String question) {
        JSONObject data = null, body = null;
        try {
            Thread.sleep(1000);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(WC_ROBOT, getHttpEntity(question), String.class);
            body = JSONUtil.parseObj(responseEntity.getBody());
            data = body.get("data", JSONObject.class)
                    .get("answer", JSONArray.class)
                    .get(0, JSONObject.class)
                    .get("txt", JSONArray.class)
                    .get(0, JSONObject.class)
                    .get("content", JSONObject.class)
                    .get("components", JSONArray.class)
                    .get(0, JSONObject.class)
                    .get("data", JSONObject.class);
        } catch (Exception e) {
            System.out.println(body);
            e.printStackTrace();
        }
        return data;
    }

    private static Map<String, Object> queryLoad(String question) {
    	///略
    }

    private static HttpEntity getHttpEntity(String question) {
    	///略
    }

    private static String getCookie() throws Exception {
    	///略
    }
}

Java爬虫实现访问问财数据并处理

运行截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

访问次数过多,java会抛出异常,这个时候打开浏览器访问问财,会被警告,这个时候验证下拼图就又可以重新验证。

在这里插入图片描述
Java爬虫实现访问问财数据并处理

以下内容可以忽略

发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/668069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RocketMQ简介

目录 MQ介绍 MQ的优点和缺点 各种MQ产品的比较 消息发送者步骤分析 消息消费者步骤分析 顺序消息 延时消息 事务消息 1&#xff09;事务消息发送及提交 2&#xff09;事务补偿 3&#xff09;事务消息状态 使用限制 重试队列 重试配置 怎么保证消息消费的时候0丢失…

Java——《面试题——MyBatis篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 目录 前文 1、什么是MyBatis 2、说说MyBatis的优点和缺点 3、#{}和${}的区别是什么&#xff1f; 4、当实体类中的属性名和…

Flask框架制作读取txt文本网页

Pycharm demo项目 app2.py&#xff08;运行&#xff09; index2.html &#xff08;网页&#xff09; 网页访问地址&#xff1a; http://127.0.0.1:5000 网页画面 核心代码(网页) 点击按钮弹窗选择 txt 文件&#xff08;index2.html&#xff09; <form method"post&…

探索CSS中的粘性定位:解锁网页布局的新可能

这篇文章详细解释了CSS中的sticky定位方式&#xff0c;并讲解了它的工作原理。 CSS中的sticky定位有很好的浏览器支持&#xff0c;但许多开发者并没有使用它。原因有两方面&#xff1a;一是等待浏览器支持的时间太长&#xff0c;导致这个特性被遗忘&#xff1b;二是大部分开发…

OpenCV项目开发实战--一步一步介绍使用 OpenPose 进行基于深度学习的人体姿势估计--C++/Python源码

文末附基于Python和C++两种方式实现的测试代码下载链接 在本教程中,使用 OpenCV 进行基于深度学习的人体姿态估计。我们将详细说明如何在您自己的应用程序中使用预训练 Caffe 模型。 1.姿态估计(又名关键点检测) 姿态估计是计算机视觉中的一个普遍问题,我们在其中检测物体…

西门子Mendix入门

首先进入网址Mendix 点击下方sign up进入带注册页面 我的注册成功后需要等会才能完成注册&#xff0c;我是下午开始注册的&#xff0c;晚上九点半的时候就可以登陆了 点击右上方create Apps 之后进入到这个页面选择应用程序模板 这里我们搜索Task选择第一个 单击Select Templa…

【Arduino+ESP32专题】Visual Studio Code界面重置为默认状态

在使用Visual Studio Code进行编程的时候&#xff0c;有时不小心把某些状态栏或功能框关闭了&#xff0c;不知道从哪里再次打开。因此有一个办法是曲线救国&#xff0c;可以让Visual Studio Code界面重置为默认状态就行了。 方式1 选择右上角Open Settings(UI)图标 打开文档把…

GC相关的

1、判断对象是否为垃圾的算法 引用计数算法可达性分析算法 引用计数算法 判断的标准&#xff1a; 通过判断对象的引用数量来决定对象是否可以被回收。 每个对象实例都有一个引用计数器&#xff0c;被引用则1&#xff0c;完成引用则-1。 任何引用计数为0的对象实例可以被当…

操作系统-I/O管理-I/O系统(设备独立性软件)

目录 一、假脱机技术(SPOOLing技术) 二、设备的分配与回收 2.1设备分配考虑因素 设备的固有属性 设备分配算法 设备分配中的安全性 2.2静态分配和动态分配 2.3设备分配管理中的数据结构 DTC COCT CHCT SDT 三、缓冲区管理 3.1单缓冲 3.2 双缓冲 ​3.2循环缓冲 3.…

1746_Perl中面向对象的目录处理模块

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 说起来我还不懂Perl的面向对象编程技术&#xff0c;只是在前阵子看到了书中提到了一句&#xff0c;用到了一个例子。今天看书的时候又看到了类型形势的代码&#xff08;代码中很…

25利用 灰色预测模型预测发电量(附matlab程序)

1.简述 学习目标&#xff1a; 灰色预测模型预测发电量 根据原始发电量数据预测需要年份的发电量 发电量预测是电力系统规划与运行的基础,是电力市场运作中的重要组成部分.目前,对发电量预测的研究已经比较深入,常用的发电量预测方法有:灰色预测法,线性回归模型,自回归移动平均模…

软件测试(1)

软件测试就是用来验证产品特性是否满足用户需求 调试是发现并解决软件中的缺陷 开发人员编码阶段进行 测试是用来发现软件中的缺陷 测试人员&#xff0c;开发人员&#xff08;单元测试&#xff0c;集成测试&#xff09; 测试贯穿于整个软件的生命周期&#xff0c;但是调…

免费在线压缩图片的网站

1. TinyPNG - 这是一个非常受欢迎的在线图片压缩网站,可以压缩 PNG 和 JPG 图片,保证无损压缩。 网址&#xff1a;TinyPNG – Compress WebP, PNG and JPEG images intelligently 2. Compressor.io - 这也是一个很好的在线图片压缩工具,可以批量上传和压缩图片,支持 PNG, JPG 和…

逆向Android开发工程,抓包!抓包!学习哪里?

抓包是什么&#xff1f; 在Android逆向工程中&#xff0c;抓包是一项重要的技术&#xff0c;用于获取手机应用程序与服务器之间的通信数据。通过抓包&#xff0c;可以分析应用程序的网络请求&#xff0c;获取请求的URL、参数、响应数据等信息&#xff0c;对应用程序的行为进行…

JavaSE进阶--注解

文章目录 前言一、概念二、使用实例1、Junit测试中2、JDK内置注解 三、自定义注解1、注解声明2、注解配置参数2.1 配置参数的类型&#xff1a;2.2 注意2.3 两个概念 3、使用注解 四、元注解1、Retention1.1 RetentionPolicy.SOURCE1.2 RetentionPolicy.CLASS1.3 RetentionPolic…

千万不要在简历里写精通C++,没人能真正精通C++

任何说自己很懂C的人可能都是在夸大其词。 我想你可能已经注意到了&#xff0c;是的&#xff0c;今天的大多数程序员都在使用Python、Rust、Go或是其他新的编程语言。大部分人已经不再需要掌握C、C等古老的编程语言了&#xff0c;甚至很多程序员已经从手动编码开始向AI编码转型…

el-select 触底分页+远程搜索

文章目录 前言一、el-select 触底分页远程搜索1.封装触底自定义指令2.在 mian.js 引入封装好的自定义指令3.在组件中进行使用 总结 前言 大部分情况下使用 el-select 的时候&#xff0c;el-options 中 options 的值都是后端接口给的数据&#xff0c;直接赋值就可以了。但是有的…

(8版本)mysql数据库安装教程(自用保存)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: mysql 参考csdn大神们的文章&#xff0c; 总结出来的详细用法~~~ 目录 文章目录 一、下载MySQL8.0.33 二、配置初始化文件my.ini(重点) 三、初始化MySQL 四、安装MySQL服务并启动 修改密码 4.1 安装…

akima 插值拟合算法 Python/C++版本

目录 前言Akima简介Akima优势 算法的代码实现python版C 版代码解析1代码解析2代码解析3 结果测试 前言 鉴于CSDN上Akima算法文章大部分要VIP观看或者下载&#xff0c;即使是付费也有质量不佳&#xff0c;浪费Money也浪费时间。 笔者更具查到的资料分享给大家。 Akima简介 Ak…

C++技能系列 ( 5 ) - 详解函数入参/返回参使用(值传递/引用传递/指针传递/智能指针传递)

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待动动小手&#xff0c;点击关注哦&#xff01;&#xff01;&#xff01; 当你休息的时候&#xff0c;一定要想到别人还在奔跑。 When you rest, we must thin…