├── 1.png
├── 2.png
├── JdKill.iml
├── .idea
├── vcs.xml
├── .gitignore
├── misc.xml
├── compiler.xml
├── jarRepositories.xml
├── artifacts
│ └── Jd_Pruchase_Kill_jar.xml
├── inspectionProfiles
│ └── Project_Default.xml
└── uiDesigner.xml
├── initData.txt
├── README.md
├── src
└── main
│ └── java
│ └── com
│ └── zx
│ └── jdkill
│ └── test
│ ├── TimeUtil.java
│ ├── BaseQuartzManager.java
│ ├── Login.java
│ ├── RushToPurchase.java
│ ├── HttpUrlConnectionUtil.java
│ └── Start.java
├── pom.xml
└── LICENSE
/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhao458114067/jd-pruchase-kill/HEAD/1.png
--------------------------------------------------------------------------------
/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhao458114067/jd-pruchase-kill/HEAD/2.png
--------------------------------------------------------------------------------
/JdKill.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /../../../../:\idea_workspace\JdKill\.idea/dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/initData.txt:
--------------------------------------------------------------------------------
1 | //每个参数后面需要加分号
2 | //商品id
3 | pid=10039884955397;
4 | //自己的eid
5 | eid=W2HEXZSRULGOBXAMFF6J44UTIGCP5QGKRQO5M7KZHYUAU7RT2JBTXRG2ZNRUWHKYX2PHNKRJI2KOM7BZIZ2V3F3C64;
6 | // 支付密码
7 | payPassword=691025;
8 | //自己的fp
9 | fp=4ce08fcab2f99f47724c9c7cdf771d9f;
10 | //获取ip代理,不会用不要填,但是必须保留分号
11 | getIpUrl=;http://api.xiequ.cn/VAD/GetIp.aspx?act=get&uid=44642&vkey=7A3390008CDA146DD0D6DD06E97858D2&num=1&time=30&plat=1&re=0&type=0&so=1&ow=1&spl=1&addr=&db=1;
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jd-Pruchase-Kill
2 |
3 | ### 扫码登陆
4 |
5 | Start.class是程序入口,exe运行必须要有jre1.8运行环境
6 |
7 | **配置文件initData.txt文件必须与.exe文件或者项目在同一目录下**
8 |
9 | ### 需要设置
10 |
11 | 商品id pid;
12 |
13 | eid = "";
14 |
15 | fp = "";
16 |
17 | 商品id为商品详情url中的一串数字
18 |
19 | eid以及fp在订单结算页面 https://trade.jd.com/shopping/order/getOrderInfo.action
20 |
21 | F12打开console,输入_JdTdudfp
22 |
23 | 
24 |
25 | 或者F12打开Sources,添加_JdTdudfp参数
26 |
27 | 
28 |
29 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/artifacts/Jd_Pruchase_Kill_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | $PROJECT_DIR$/out/artifacts/Jd_Pruchase_Kill_jar
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/main/java/com/zx/jdkill/test/TimeUtil.java:
--------------------------------------------------------------------------------
1 | package com.zx.jdkill.test;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 |
7 | /**
8 | * @author : zhaoxu
9 | */
10 | public class TimeUtil {
11 | public static final String PATTERN_YMD_HMS = "yyyy-MM-dd HH:mm:ss";
12 | public static final String PATTERN_YMD = "yyyy-MM-dd HH:mm:ss";
13 | public static final String PATTERN_TARGET_TIME = "ss mm HH dd MM ? yyyy";
14 |
15 |
16 | /**
17 | * time时间戳转Date
18 | *
19 | * @param time
20 | * @return
21 | */
22 | public static Date timeToDate(String time, String pattern) {
23 | SimpleDateFormat sdfTime = new SimpleDateFormat(pattern);
24 | String str = sdfTime.format(Long.valueOf(time));
25 | try {
26 | Date date = sdfTime.parse(str);
27 | return date;
28 | } catch (ParseException e) {
29 | e.printStackTrace();
30 | }
31 | return null;
32 | }
33 |
34 | /**
35 | * 日期字符串转String型Time
36 | *
37 | * @param date
38 | * @return
39 | */
40 | public static String stringToTime(String date, String pattern) {
41 | SimpleDateFormat sdfTime = new SimpleDateFormat(pattern);
42 | try {
43 | Date dateDate = sdfTime.parse(date);
44 | return String.valueOf(dateDate.getTime());
45 | } catch (ParseException e) {
46 | e.printStackTrace();
47 | }
48 | return null;
49 | }
50 |
51 | /**
52 | * 将日期转化为对应的格式
53 | * @param date
54 | * @param dateFormat
55 | * @return
56 | */
57 | public static String formatDateByPattern(Date date, String dateFormat){
58 | SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
59 | String formatTimeStr = null;
60 | if (date != null) {
61 | formatTimeStr = sdf.format(date);
62 | }
63 | return formatTimeStr;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | Jd-Pruchase-Kill
8 | Jd-Pruchase-Kill
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 | org.apache.maven.plugins
14 | maven-compiler-plugin
15 |
16 | 8
17 | 8
18 |
19 |
20 |
21 |
22 |
23 |
24 | net.java.dev.jna
25 | jna
26 | 5.0.0
27 |
28 |
29 | net.java.dev.jna
30 | jna-platform
31 | 5.0.0
32 |
33 |
34 | com.alibaba
35 | fastjson
36 | 1.2.62
37 |
38 |
39 | org.apache.httpcomponents
40 | httpclient
41 | 4.5.13
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-quartz
46 | 2.1.5.RELEASE
47 |
48 |
49 | org.projectlombok
50 | lombok
51 | 1.18.22
52 | compile
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/main/java/com/zx/jdkill/test/BaseQuartzManager.java:
--------------------------------------------------------------------------------
1 | package com.zx.jdkill.test;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.quartz.*;
6 | import org.quartz.impl.StdSchedulerFactory;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.transaction.annotation.Isolation;
9 | import org.springframework.transaction.annotation.Transactional;
10 |
11 | import java.util.Calendar;
12 |
13 | /**
14 | * @author ZhaoXu
15 | * @date 2022/5/31 17:03
16 | */
17 | @Slf4j
18 | @Service
19 | public class BaseQuartzManager {
20 |
21 | Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
22 |
23 | public BaseQuartzManager() throws SchedulerException {
24 | }
25 |
26 |
27 | public void createJob(Class extends Job> jobClass, String jobName, String jobGroupName, String cronExpression, JSONObject params, boolean exeOnce) {
28 | // 创建scheduler,调度器, 策略采用错过之后立即执行一次
29 | CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionFireAndProceed();
30 | Trigger trigger = TriggerBuilder.newTrigger()
31 | .withIdentity(jobName, jobGroupName)
32 | .startNow()
33 | .withSchedule(scheduleBuilder)
34 | .build();
35 | // 定义一个JobDetail
36 | JobDetail jobDetail = JobBuilder.newJob(jobClass)
37 | .withIdentity(jobName, jobGroupName)
38 | .build();
39 | trigger.getJobDataMap().putAll(params);
40 | try {
41 | scheduler.scheduleJob(jobDetail, trigger);
42 | // 启动任务调度
43 | scheduler.start();
44 | } catch (Exception e) {
45 | log.error("创建定时任务失败,jobName:{},jobGroupName:{}", jobName, jobGroupName);
46 | throw new RuntimeException(e);
47 | }
48 | log.info("创建定时任务成功,jobName:{},jobGroupName:{}", jobName, jobGroupName);
49 | }
50 |
51 | @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
52 | public void deleteJob(String jobName, String jobGroupName) {
53 | try {
54 | scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
55 | scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
56 | scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
57 | } catch (Exception e) {
58 | log.error("删除定时任务失败,jobName:{},jobGroupName:{}", jobName, jobGroupName);
59 | }
60 | log.info("删除定时任务成功,jobName:{},jobGroupName:{}", jobName, jobGroupName);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/zx/jdkill/test/Login.java:
--------------------------------------------------------------------------------
1 | package com.zx.jdkill.test;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.sun.jna.Native;
5 | import com.sun.jna.Pointer;
6 | import com.sun.jna.platform.win32.User32;
7 | import com.sun.jna.platform.win32.WinDef;
8 | import com.sun.jna.platform.win32.WinUser;
9 |
10 | import java.io.IOException;
11 | import java.net.URI;
12 | import java.net.URISyntaxException;
13 | import java.util.HashMap;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | /**
18 | * @author: zhaoxu
19 | * @date: 2021/1/9 18:59
20 | */
21 | public class Login {
22 | static String venderId = "";
23 | static Map> requestHeaders = new HashMap>(16);
24 | static String ticket = "";
25 |
26 | public static void Login() throws IOException, URISyntaxException, InterruptedException {
27 | JSONObject headers = new JSONObject();
28 | headers.put(Start.HEADER_AGENT, Start.HEADER_AGENT_ARG);
29 | headers.put(Start.REFERER, Start.REFERER_ARG);
30 | //获取二维码
31 | long now = System.currentTimeMillis();
32 | HttpUrlConnectionUtil.getQCode(headers, "https://qr.m.jd.com/show?appid=133&size=147&t=" + now);
33 | //打开二维码
34 | Runtime.getRuntime().exec("cmd /c QCode.png");
35 | URI url = new URI("https://qr.m.jd.com/show?appid=133&size=147&t=" + now);
36 | Map> stringListMap = new HashMap>();
37 | stringListMap = Start.manager.get(url, requestHeaders);
38 | List cookieList = stringListMap.get("Cookie");
39 | String cookies = cookieList.get(0);
40 | String token = cookies.split("wlfstk_smdl=")[1];
41 | headers.put("Cookie", cookies);
42 | //判断是否扫二维码
43 | while (true) {
44 | String checkUrl = "https://qr.m.jd.com/check?appid=133&callback=jQuery" + (int) ((Math.random() * (9999999 - 1000000 + 1)) + 1000000) + "&token=" + token + "&_=" + System.currentTimeMillis();
45 | String qrCode = HttpUrlConnectionUtil.get(headers, checkUrl);
46 | if (qrCode.contains("二维码未扫描")) {
47 | System.out.println("二维码未扫描,请扫描二维码登录");
48 | } else if (qrCode.contains("请手机客户端确认登录")) {
49 | System.out.println("请手机客户端确认登录");
50 | } else {
51 | ticket = qrCode.split("\"ticket\" : \"")[1].split("\"\n" +
52 | "}\\)")[0];
53 | System.out.println("已完成二维码扫描登录");
54 | close();
55 | break;
56 | }
57 | Thread.sleep(1000);
58 | }
59 | //验证,获取cookie
60 | String qrCodeTicketValidation = HttpUrlConnectionUtil.get(headers, "https://passport.jd.com/uc/qrCodeTicketValidation?t=" + ticket);
61 | stringListMap = Start.manager.get(url, requestHeaders);
62 | cookieList = stringListMap.get("Cookie");
63 | cookies = cookieList.get(0).toString();
64 | headers.put("Cookie", cookies);
65 | }
66 |
67 | public static void close() {
68 | // 通过窗口标题获取窗口句柄
69 | WinDef.HWND hWnd;
70 | final User32 user32 = User32.INSTANCE;
71 | user32.EnumWindows(new WinUser.WNDENUMPROC() {
72 | @Override
73 | public boolean callback(WinDef.HWND hWnd, Pointer arg1) {
74 | char[] windowText = new char[512];
75 | user32.GetWindowText(hWnd, windowText, 512);
76 | String wText = Native.toString(windowText);
77 | if (wText.isEmpty()) {
78 | return true;
79 | }
80 | if (wText.contains("照片")) {
81 | hWnd = User32.INSTANCE.FindWindow(null, wText);
82 | WinDef.LRESULT lresult = User32.INSTANCE.SendMessage(hWnd, 0X10, null, null);
83 | }
84 | return true;
85 | }
86 | }, null);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/zx/jdkill/test/RushToPurchase.java:
--------------------------------------------------------------------------------
1 | package com.zx.jdkill.test;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import org.quartz.Job;
5 | import org.quartz.JobExecutionContext;
6 | import org.quartz.JobExecutionException;
7 | import org.springframework.util.StringUtils;
8 |
9 | import java.io.IOException;
10 | import java.net.InetAddress;
11 | import java.net.URI;
12 | import java.net.URISyntaxException;
13 | import java.util.ArrayList;
14 | import java.util.HashMap;
15 | import java.util.List;
16 | import java.util.Map;
17 |
18 |
19 | /**
20 | * @author: zhaoxu
21 | * @date: 2021/1/8 20:51
22 | */
23 | public class RushToPurchase implements Job {
24 | /**
25 | * 请求头
26 | */
27 | static Map> stringListMap = new HashMap<>(16);
28 |
29 | public static void setIpProxy() {
30 | try {
31 | String hostAddress = InetAddress.getLocalHost().getHostAddress();
32 | System.getProperties().setProperty("http.proxyHost", hostAddress);
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | try {
37 | String response = HttpUrlConnectionUtil.get(null, Start.getIpUrl);
38 | System.out.println("设置代理:" + response);
39 | String[] split = response.split(":");
40 | System.getProperties().setProperty("http.proxyHost", split[0]);
41 | System.getProperties().setProperty("http.proxyPort", split[1]);
42 | } catch (IOException e) {
43 | throw new RuntimeException(e);
44 | }
45 | }
46 |
47 | @Override
48 | public void execute(JobExecutionContext jobExecutionContext) {
49 | JSONObject headers = new JSONObject();
50 | headers.put(Start.HEADER_AGENT, Start.HEADER_AGENT_ARG);
51 | headers.put(Start.REFERER, Start.REFERER_ARG);
52 |
53 | // 加入购物车
54 | String gate = null;
55 | List cookie = new ArrayList<>();
56 | try {
57 | gate = HttpUrlConnectionUtil.get(headers, "https://cart.jd.com/gate.action?pcount=1&ptype=1&pid=" + Start.pid);
58 | } catch (IOException e) {
59 | throw new RuntimeException(e);
60 | }
61 |
62 | //订单信息
63 | stringListMap.clear();
64 | try {
65 | stringListMap = Start.manager.get(new URI("https://trade.jd.com/shopping/order/getOrderInfo.action"), stringListMap);
66 | } catch (URISyntaxException e) {
67 | e.printStackTrace();
68 | }
69 | cookie = stringListMap.get("Cookie");
70 | headers.put("Cookie", cookie.get(0).toString());
71 | try {
72 | String orderInfo = HttpUrlConnectionUtil.get(headers, "https://trade.jd.com/shopping/order/getOrderInfo.action");
73 | System.out.println(orderInfo);
74 | } catch (IOException e) {
75 | e.printStackTrace();
76 | }
77 |
78 | //提交订单
79 | JSONObject subData = new JSONObject();
80 | headers = new JSONObject();
81 | subData.put("overseaPurchaseCookies", "");
82 | subData.put("submitOrderParam.payPassword", Start.gbEncoding(Start.payPassword).replace("\\", ""));
83 | subData.put("vendorRemarks", "[]");
84 | subData.put("submitOrderParam.sopNotPutInvoice", "false");
85 | subData.put("submitOrderParam.ignorePriceChange", "1");
86 | subData.put("submitOrderParam.btSupport", "0");
87 | subData.put("submitOrderParam.isBestCoupon", "1");
88 | subData.put("submitOrderParam.jxj", "1");
89 | subData.put("submitOrderParam.trackID", Login.ticket);
90 | subData.put("submitOrderParam.eid", Start.eid);
91 | subData.put("submitOrderParam.fp", Start.fp);
92 | subData.put("submitOrderParam.needCheck", "1");
93 |
94 | headers.put("Referer", "http://trade.jd.com/shopping/order/getOrderInfo.action");
95 | headers.put("origin", "https://trade.jd.com");
96 | headers.put("Content-Type", "application/json");
97 | headers.put("x-requested-with", "XMLHttpRequest");
98 | headers.put("upgrade-insecure-requests", "1");
99 | headers.put("sec-fetch-user", "?1");
100 | stringListMap.clear();
101 |
102 | try {
103 | stringListMap = Start.manager.get(new URI("https://trade.jd.com/shopping/order/getOrderInfo.action"), stringListMap);
104 | } catch (URISyntaxException e) {
105 | e.printStackTrace();
106 | }
107 | cookie = stringListMap.get("Cookie");
108 | headers.put("Cookie", cookie.get(0).toString());
109 | String submitOrder = null;
110 | try {
111 | //获取ip,使用的是免费的 携趣代理 ,不需要或者不会用可以注释掉
112 | if (!StringUtils.isEmpty(Start.getIpUrl)) {
113 | setIpProxy();
114 | }
115 | submitOrder = HttpUrlConnectionUtil.post(headers, "https://trade.jd.com/shopping/order/submitOrder.action", subData);
116 | } catch (IOException e) {
117 | e.printStackTrace();
118 | }
119 | if (submitOrder.contains("刷新太频繁了") || submitOrder.contains("抱歉,您访问的内容不存在")) {
120 | System.out.println("刷新太频繁了,您访问的内容不存在");
121 | }
122 | JSONObject jsonObject = JSONObject.parseObject(submitOrder);
123 | String success = null;
124 | String message = null;
125 | if (jsonObject != null && jsonObject.get("success") != null) {
126 | success = jsonObject.get("success").toString();
127 | }
128 | if (jsonObject != null && jsonObject.get("message") != null) {
129 | message = jsonObject.get("message").toString();
130 | }
131 | if ("true".equals(success)) {
132 | System.out.println("已成功抢购,请尽快完成付款");
133 | } else {
134 | if (message != null) {
135 | System.out.println(message);
136 | }
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/main/java/com/zx/jdkill/test/HttpUrlConnectionUtil.java:
--------------------------------------------------------------------------------
1 | package com.zx.jdkill.test;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 |
5 | import java.io.*;
6 | import java.net.HttpURLConnection;
7 | import java.net.URL;
8 | import java.text.ParseException;
9 | import java.text.SimpleDateFormat;
10 | import java.util.ArrayList;
11 | import java.util.Date;
12 | import java.util.Iterator;
13 |
14 | /**
15 | * @author: zhaoxu
16 | * @date: 2021/1/5 22:26
17 | */
18 | public class HttpUrlConnectionUtil {
19 |
20 | /**
21 | * get请求
22 | *
23 | * @param headers 请求头,可为空
24 | * @param url
25 | * @return
26 | * @throws IOException
27 | */
28 | public static String get(JSONObject headers, String url) throws IOException {
29 | String response = "";
30 | HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
31 | httpURLConnection.setRequestMethod("GET");
32 | if (headers != null) {
33 | Iterator iterator = headers.keySet().iterator();
34 | while (iterator.hasNext()) {
35 | String headerName = iterator.next();
36 | httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
37 | }
38 | }
39 | httpURLConnection.connect();
40 | if (httpURLConnection.getResponseCode() == 200) {
41 | InputStream inputStream = httpURLConnection.getInputStream();
42 | byte[] buffer;
43 | buffer = new byte[1024];
44 | int length = 0;
45 | while ((length = inputStream.read(buffer)) != -1) {
46 | response = response + new String(buffer, 0, length, "UTF-8");
47 | }
48 | httpURLConnection.disconnect();
49 | }
50 | return response;
51 | }
52 |
53 | /**
54 | * post请求
55 | *
56 | * @param headers 请求头,可为空
57 | * @param url
58 | * @param params post请求体,可为空
59 | * @return
60 | * @throws IOException
61 | */
62 | public static String post(JSONObject headers, String url, JSONObject params) throws IOException {
63 | String response = "";
64 | HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
65 | httpURLConnection.setRequestMethod("POST");
66 | if (headers != null) {
67 | Iterator iterator = headers.keySet().iterator();
68 | while (iterator.hasNext()) {
69 | String headerName = iterator.next();
70 | httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
71 | }
72 | }
73 | httpURLConnection.setDoOutput(true);
74 | httpURLConnection.connect();
75 | if (params != null) {
76 | httpURLConnection.getOutputStream().write(params.toJSONString().getBytes("UTF-8"));
77 | }
78 | httpURLConnection.getInputStream();
79 | if (httpURLConnection.getResponseCode() == 200) {
80 | InputStream inputStream = httpURLConnection.getInputStream();
81 | byte[] buffer;
82 | buffer = new byte[1024];
83 | int length = 0;
84 | while ((length = inputStream.read(buffer)) != -1) {
85 | response = response + new String(buffer, 0, length, "UTF-8");
86 | }
87 | httpURLConnection.disconnect();
88 | }
89 | httpURLConnection.disconnect();
90 | return response;
91 | }
92 |
93 | /**
94 | * 获取并保存二维码
95 | *
96 | * @param headers
97 | * @param url
98 | * @return
99 | * @throws IOException
100 | */
101 | public static String getQCode(JSONObject headers, String url) throws IOException {
102 | String response = "";
103 | HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
104 | httpURLConnection.setRequestMethod("GET");
105 | if (headers != null) {
106 | Iterator iterator = headers.keySet().iterator();
107 | while (iterator.hasNext()) {
108 | String headerName = iterator.next();
109 | httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
110 | }
111 | }
112 | httpURLConnection.connect();
113 | if (httpURLConnection.getResponseCode() == 200) {
114 | InputStream inputStream = httpURLConnection.getInputStream();
115 | OutputStream outputStream = new FileOutputStream("QCode.png");
116 | byte[] buffer;
117 | int length;
118 | buffer = new byte[1024];
119 | while ((length = inputStream.read(buffer)) != -1) {
120 | outputStream.write(buffer, 0, length);
121 | response = response + new String(buffer, 0, length, "UTF-8");
122 | }
123 | outputStream.close();
124 | httpURLConnection.disconnect();
125 | }
126 | return response;
127 | }
128 |
129 | /**
130 | * date字符串转时间戳
131 | *
132 | * @param date
133 | * @return
134 | */
135 | public static Long dateToTime(String date) throws ParseException {
136 | SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
137 | Date data = sdfTime.parse(date);
138 | Long time = data.getTime();
139 | return time;
140 | }
141 |
142 | /**
143 | * time时间戳转Date
144 | *
145 | * @param time
146 | * @return
147 | */
148 | public static Date timeToDate(String time) {
149 | SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
150 | String str = sdfTime.format(Long.valueOf(time));
151 | try {
152 | Date date = sdfTime.parse(str);
153 | return date;
154 | } catch (ParseException e) {
155 | e.printStackTrace();
156 | }
157 | return null;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/main/java/com/zx/jdkill/test/Start.java:
--------------------------------------------------------------------------------
1 | package com.zx.jdkill.test;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.sun.webkit.network.CookieManager;
5 | import org.quartz.SchedulerException;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.io.InputStreamReader;
11 | import java.net.CookieHandler;
12 | import java.net.URISyntaxException;
13 | import java.text.ParseException;
14 | import java.util.Date;
15 | import java.util.concurrent.Executors;
16 | import java.util.concurrent.PriorityBlockingQueue;
17 | import java.util.concurrent.ThreadPoolExecutor;
18 | import java.util.concurrent.TimeUnit;
19 |
20 | /**
21 | * @author: zhaoxu
22 | * @date: 2021/1/8 20:59
23 | */
24 | public class Start {
25 | final static String HEADER_AGENT = "User-Agent";
26 | final static String HEADER_AGENT_ARG = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36";
27 | final static String REFERER = "Referer";
28 | final static String REFERER_ARG = "https://passport.jd.com/new/login.aspx";
29 | //商品id
30 | static String pid = "";
31 | //eid
32 | static String eid = "";
33 | static String payPassword = "";
34 | //fp
35 | static String fp = "";
36 | //抢购数量
37 | static Integer ok = 2;
38 | //获取ip代理
39 | static String getIpUrl = "";
40 |
41 | static CookieManager manager = new CookieManager();
42 |
43 | public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException, ParseException {
44 | initData();
45 | CookieHandler.setDefault(manager);
46 | //登录
47 | Login.Login();
48 |
49 | // 设置目标任务
50 | judgePruchase();
51 | }
52 |
53 | public static void initData() throws IOException {
54 | String fileData = readFile("initData.txt").toString();
55 | try {
56 | pid = fileData.split("pid=")[1].split(";")[0];
57 | eid = fileData.split("eid=")[1].split(";")[0];
58 | fp = fileData.split("fp=")[1].split(";")[0];
59 | // ok = Integer.valueOf(fileData.split("ok=")[1].split(";")[0]);
60 | getIpUrl = fileData.split("getIpUrl=")[1].split(";")[0];
61 | payPassword = fileData.split("payPassword=")[1].split(";")[0];
62 | } catch (Exception e) {
63 | System.out.println("参数错误,每个参数后面需要加分号");
64 | }
65 |
66 | }
67 |
68 | public static void judgePruchase() throws IOException, ParseException {
69 | //获取开始时间
70 | JSONObject headers = new JSONObject();
71 | headers.put(HEADER_AGENT, HEADER_AGENT_ARG);
72 | headers.put(REFERER, REFERER_ARG);
73 | JSONObject shopDetail = JSONObject.parseObject(HttpUrlConnectionUtil.get(headers, "https://item-soa.jd.com/getWareBusiness?skuId=" + pid));
74 | BaseQuartzManager baseQuartzManager;
75 | try {
76 | baseQuartzManager = new BaseQuartzManager();
77 | } catch (SchedulerException e) {
78 | throw new RuntimeException(e);
79 | }
80 | if (shopDetail.get("yuyueInfo") != null) {
81 | String buyDate = JSONObject.parseObject(shopDetail.get("yuyueInfo").toString()).get("buyTime").toString();
82 | String startDate = buyDate.split("-202")[0] + ":00";
83 | long startTime = HttpUrlConnectionUtil.dateToTime(startDate);
84 | if (startTime <= System.currentTimeMillis()) {
85 | for (int i = 0; i < 5; i++) {
86 | baseQuartzManager.createJob(RushToPurchase.class, "RushToPurchase-" + i, "RushToPurchase",
87 | TimeUtil.formatDateByPattern(new Date(), TimeUtil.PATTERN_TARGET_TIME), new JSONObject(), true);
88 | }
89 | } else {
90 | //获取京东时间
91 | JSONObject jdTime = JSONObject.parseObject(HttpUrlConnectionUtil.get(headers, "https://api.m.jd.com/client.action?functionId=queryMaterialProducts&client=wh5"));
92 | long serverTime = Long.parseLong(jdTime.get("currentTime2").toString());
93 | for (int i = 0; i < 100; i++) {
94 | int random = (int) (Math.random() * (40 - 5 + 1)) + 5;
95 | long localStartTime = startTime - serverTime + System.currentTimeMillis() - random;
96 | String cornExpression = TimeUtil.formatDateByPattern(new Date(localStartTime), TimeUtil.PATTERN_TARGET_TIME);
97 | baseQuartzManager.createJob(RushToPurchase.class, "RushToPurchase-" + i, "RushToPurchase",
98 | cornExpression, new JSONObject(), true);
99 | }
100 | }
101 | } else {
102 | for (int i = 0; i < 5; i++) {
103 | baseQuartzManager.createJob(RushToPurchase.class, "RushToPurchase-" + i, "RushToPurchase",
104 | TimeUtil.formatDateByPattern(new Date(), TimeUtil.PATTERN_TARGET_TIME), new JSONObject(), true);
105 | }
106 | }
107 | }
108 |
109 | /**
110 | * 按行读取全部文件数据
111 | *
112 | * @param strFile
113 | */
114 | public static StringBuffer readFile(String strFile) throws IOException {
115 | StringBuffer strSb = new StringBuffer();
116 | InputStreamReader inStrR = new InputStreamReader(new FileInputStream(strFile), "UTF-8");
117 | // character streams
118 | BufferedReader br = new BufferedReader(inStrR);
119 | String line = br.readLine();
120 | while (line != null) {
121 | strSb.append(line).append("\r\n");
122 | line = br.readLine();
123 | }
124 | return strSb;
125 | }
126 |
127 | /*
128 | * 中文转unicode编码
129 | */
130 | public static String gbEncoding(final String gbString) {
131 | char[] utfBytes = gbString.toCharArray();
132 | String unicodeBytes = "";
133 | for (int i = 0; i < utfBytes.length; i++) {
134 | String hexB = Integer.toHexString(utfBytes[i]);
135 | if (hexB.length() <= 2) {
136 | hexB = "00" + hexB;
137 | }
138 | unicodeBytes = unicodeBytes + "\\u" + hexB;
139 | }
140 | return unicodeBytes;
141 | }
142 |
143 | /*
144 | * unicode编码转中文
145 | */
146 | public static String decodeUnicode(final String dataStr) {
147 | int start = 0;
148 | int end = 0;
149 | final StringBuffer buffer = new StringBuffer();
150 | while (start > -1) {
151 | end = dataStr.indexOf("\\u", start + 2);
152 | String charStr = "";
153 | if (end == -1) {
154 | charStr = dataStr.substring(start + 2, dataStr.length());
155 | } else {
156 | charStr = dataStr.substring(start + 2, end);
157 | }
158 | char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。
159 | buffer.append(new Character(letter).toString());
160 | start = end;
161 | }
162 | return buffer.toString();
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------