通过 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爬虫实现访问问财数据并处理
以下内容可以忽略
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】
发文助手会检测您的文章标题、错别字、内容质量,助您提升文章质量。【创作规范】