├── COPYING.md
├── README.md
├── pom.xml
└── src
└── main
└── java
└── com
└── jd
└── seckill
├── HttpUrlConnectionUtil.java
├── Login.java
├── RushToPurchase.java
└── Start.java
/COPYING.md:
--------------------------------------------------------------------------------
1 | ## 声明
2 | - 使用此仓库中的任何代码皆视为已接受此声明
3 | - 此仓库中的任何代码仅用于测试和学习,禁止用于任何商业用途
4 | - 此仓库中的任何代码禁止转载或发布至除github.com以外的任何站点
5 | - 此仓库的作者不对此仓库中的任何代码负任何责任
6 | - 使用此仓库中的任何代码所造成的任何法律问题,与此仓库的作者无关
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 环境
2 |
3 | - Windows 10
4 | - Oracle JDK 8
5 |
6 | ## 使用
7 |
8 | - 编辑Start.java
9 | - 运行Class Start
10 | - 输入商品ID
11 | - 输入商品数量
12 | - 扫码登录
13 |
14 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.jd.seckill
7 | jd-seckill
8 | 1.0-SNAPSHOT
9 |
10 |
11 |
12 | org.apache.maven.plugins
13 | maven-compiler-plugin
14 |
15 | 8
16 | 8
17 |
18 |
19 |
20 |
21 |
22 |
23 | net.java.dev.jna
24 | jna
25 | 5.0.0
26 |
27 |
28 | net.java.dev.jna
29 | jna-platform
30 | 5.0.0
31 |
32 |
33 | com.alibaba
34 | fastjson
35 | 1.2.72
36 |
37 |
38 | org.apache.httpcomponents
39 | httpclient
40 | 4.5.13
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/main/java/com/jd/seckill/HttpUrlConnectionUtil.java:
--------------------------------------------------------------------------------
1 | package com.jd.seckill;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 |
5 | import java.io.BufferedReader;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.io.InputStreamReader;
10 | import java.io.OutputStream;
11 | import java.net.HttpURLConnection;
12 | import java.net.URL;
13 | import java.text.ParseException;
14 | import java.text.SimpleDateFormat;
15 | import java.util.ArrayList;
16 | import java.util.Date;
17 | import java.util.Iterator;
18 |
19 | public class HttpUrlConnectionUtil {
20 |
21 | public static String get(JSONObject headers, String url) throws IOException {
22 | String response = "";
23 | HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
24 | httpURLConnection.setRequestMethod("GET");
25 | if (headers != null) {
26 | Iterator iterator = headers.keySet().iterator();
27 | while (iterator.hasNext()) {
28 | String headerName = iterator.next();
29 | httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
30 | }
31 | }
32 | httpURLConnection.connect();
33 | if (httpURLConnection.getResponseCode() == 200) {
34 | InputStream inputStream = httpURLConnection.getInputStream();
35 | byte[] buffer;
36 | buffer = new byte[1024];
37 | int length = 0;
38 | while ((length = inputStream.read(buffer)) != -1) {
39 | response = response + new String(buffer, 0, length, "UTF-8");
40 | }
41 | httpURLConnection.disconnect();
42 | }
43 | return response;
44 | }
45 |
46 | public static String post(JSONObject headers, String url, JSONObject params) throws IOException {
47 | String response = "";
48 | HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
49 | httpURLConnection.setRequestMethod("POST");
50 | if (headers != null) {
51 | Iterator iterator = headers.keySet().iterator();
52 | while (iterator.hasNext()) {
53 | String headerName = iterator.next();
54 | httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
55 | }
56 | }
57 | httpURLConnection.setDoOutput(true);
58 | httpURLConnection.connect();
59 | if (params != null) {
60 | httpURLConnection.getOutputStream().write(params.toJSONString().getBytes("UTF-8"));
61 | }
62 | httpURLConnection.getInputStream();
63 | if (httpURLConnection.getResponseCode() == 200) {
64 | InputStream inputStream = httpURLConnection.getInputStream();
65 | byte[] buffer;
66 | buffer = new byte[1024];
67 | int length = 0;
68 | while ((length = inputStream.read(buffer)) != -1) {
69 | response = response + new String(buffer, 0, length, "UTF-8");
70 | }
71 | httpURLConnection.disconnect();
72 | }
73 | httpURLConnection.disconnect();
74 | return response;
75 | }
76 |
77 | public static String getQCode(JSONObject headers, String url) throws IOException {
78 | String response = "";
79 | HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
80 | httpURLConnection.setRequestMethod("GET");
81 | if (headers != null) {
82 | Iterator iterator = headers.keySet().iterator();
83 | while (iterator.hasNext()) {
84 | String headerName = iterator.next();
85 | httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
86 | }
87 | }
88 | httpURLConnection.connect();
89 | if (httpURLConnection.getResponseCode() == 200) {
90 | InputStream inputStream = httpURLConnection.getInputStream();
91 | OutputStream outputStream = new FileOutputStream("QCode.png");
92 | byte[] buffer;
93 | int length;
94 | buffer = new byte[1024];
95 | while ((length = inputStream.read(buffer)) != -1) {
96 | outputStream.write(buffer, 0, length);
97 | response = response + new String(buffer, 0, length, "UTF-8");
98 | }
99 | outputStream.close();
100 | httpURLConnection.disconnect();
101 | }
102 | return response;
103 | }
104 |
105 | public static Long dateToTime(String date) throws ParseException {
106 | SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
107 | Date data = sdfTime.parse(date);
108 | Long time = data.getTime();
109 | return time;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/jd/seckill/Login.java:
--------------------------------------------------------------------------------
1 | package com.jd.seckill;
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 | public class Login {
18 |
19 | static Map> requestHeaders = new HashMap>(16);
20 | static String ticket = "";
21 |
22 | public static void login() throws IOException, URISyntaxException, InterruptedException {
23 | JSONObject headers = new JSONObject();
24 | headers.put(Start.headerAgent, Start.headerAgentArg);
25 | headers.put(Start.Referer, Start.RefererArg);
26 | Long now = System.currentTimeMillis();
27 | HttpUrlConnectionUtil.getQCode(headers, "https://qr.m.jd.com/show?appid=133&size=147&t=" + now);
28 | Runtime.getRuntime().exec("cmd /c QCode.png");
29 | URI url = new URI("https://qr.m.jd.com/show?appid=133&size=147&t=" + now);
30 | Map> stringListMap = new HashMap>();
31 | stringListMap = Start.manager.get(url, requestHeaders);
32 | List cookieList = stringListMap.get("Cookie");
33 | String cookies = cookieList.get(0).toString();
34 | String token = cookies.split("wlfstk_smdl=")[1];
35 | headers.put("Cookie", cookies);
36 | while (true) {
37 | String checkUrl = "https://qr.m.jd.com/check?appid=133&callback=jQuery" + (int) ((Math.random() * (9999999 - 1000000 + 1)) + 1000000) + "&token=" + token + "&_=" + System.currentTimeMillis();
38 | String qrCode = HttpUrlConnectionUtil.get(headers, checkUrl);
39 | if (qrCode.indexOf("二维码未扫描") != -1) {
40 | System.out.println("二维码未扫描,请扫描二维码登录");
41 | } else if (qrCode.indexOf("请手机客户端确认登录") != -1) {
42 | System.out.println("请手机客户端确认登录");
43 | } else {
44 | ticket = qrCode.split("\"ticket\" : \"")[1].split("\"\n" +
45 | "}\\)")[0];
46 | System.out.println("已完成二维码扫描登录");
47 | close();
48 | break;
49 | }
50 | Thread.sleep(3000);
51 | }
52 | String qrCodeTicketValidation = HttpUrlConnectionUtil.get(headers, "https://passport.jd.com/uc/qrCodeTicketValidation?t=" + ticket);
53 | stringListMap = Start.manager.get(url, requestHeaders);
54 | cookieList = stringListMap.get("Cookie");
55 | cookies = cookieList.get(0).toString();
56 | headers.put("Cookie", cookies);
57 | }
58 |
59 | public static void close() throws IOException, InterruptedException {
60 | WinDef.HWND hWnd;
61 | final User32 user32 = User32.INSTANCE;
62 | user32.EnumWindows(new WinUser.WNDENUMPROC() {
63 | @Override
64 | public boolean callback(WinDef.HWND hWnd, Pointer arg1) {
65 | char[] windowText = new char[512];
66 | user32.GetWindowText(hWnd, windowText, 512);
67 | String wText = Native.toString(windowText);
68 | if (wText.isEmpty()) {
69 | return true;
70 | }
71 | if (wText.contains("照片")) {
72 | hWnd = User32.INSTANCE.FindWindow(null, wText);
73 | WinDef.LRESULT lresult = User32.INSTANCE.SendMessage(hWnd, 0X10, null, null);
74 | }
75 | return true;
76 | }
77 | }, null);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/jd/seckill/RushToPurchase.java:
--------------------------------------------------------------------------------
1 | package com.jd.seckill;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 |
5 | import java.io.IOException;
6 | import java.net.URI;
7 | import java.net.URISyntaxException;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | public class RushToPurchase implements Runnable {
13 |
14 | volatile static Integer times = 0;
15 | static Map> stringListMap = new HashMap>();
16 |
17 | public void run() {
18 | JSONObject headers = new JSONObject();
19 | while (times < Start.ok) {
20 | headers.put(Start.headerAgent, Start.headerAgentArg);
21 | headers.put(Start.Referer, Start.RefererArg);
22 | String gate = null;
23 | try {
24 | gate = HttpUrlConnectionUtil.get(headers, "https://cart.jd.com/gate.action?pcount=1&ptype=1&pid=" + Start.pid);
25 | } catch (IOException e) {
26 | e.printStackTrace();
27 | }
28 | stringListMap.clear();
29 | try {
30 | stringListMap = Start.manager.get(new URI("https://trade.jd.com/shopping/order/getOrderInfo.action"), stringListMap);
31 | } catch (URISyntaxException e) {
32 | e.printStackTrace();
33 | }
34 | List cookie = stringListMap.get("Cookie");
35 | headers.put("Cookie", cookie.get(0).toString());
36 | try {
37 | String orderInfo = HttpUrlConnectionUtil.get(headers, "https://trade.jd.com/shopping/order/getOrderInfo.action");
38 | } catch (IOException e) {
39 | e.printStackTrace();
40 | }
41 | JSONObject subData = new JSONObject();
42 | headers = new JSONObject();
43 | subData.put("overseaPurchaseCookies", "");
44 | subData.put("vendorRemarks", "[]");
45 | subData.put("submitOrderParam.sopNotPutInvoice", "false");
46 | subData.put("submitOrderParam.ignorePriceChange", "1");
47 | subData.put("submitOrderParam.btSupport", "0");
48 | subData.put("submitOrderParam.isBestCoupon", "1");
49 | subData.put("submitOrderParam.jxj", "1");
50 | subData.put("submitOrderParam.trackID", Login.ticket);
51 | subData.put("submitOrderParam.eid", Start.eid);
52 | subData.put("submitOrderParam.fp", Start.fp);
53 | subData.put("submitOrderParam.needCheck", "1");
54 | headers.put("Referer", "http://trade.jd.com/shopping/order/getOrderInfo.action");
55 | headers.put("origin", "https://trade.jd.com");
56 | headers.put("Content-Type", "application/json");
57 | headers.put("x-requested-with", "XMLHttpRequest");
58 | headers.put("upgrade-insecure-requests", "1");
59 | headers.put("sec-fetch-user", "?1");
60 | stringListMap.clear();
61 | try {
62 | stringListMap = Start.manager.get(new URI("https://trade.jd.com/shopping/order/getOrderInfo.action"), stringListMap);
63 | } catch (URISyntaxException e) {
64 | e.printStackTrace();
65 | }
66 | cookie = stringListMap.get("Cookie");
67 | headers.put("Cookie", cookie.get(0).toString());
68 | String submitOrder = null;
69 | try {
70 | if (times < Start.ok) {
71 | submitOrder = HttpUrlConnectionUtil.post(headers, "https://trade.jd.com/shopping/order/submitOrder.action", null);
72 | } else {
73 | System.out.println("已抢购" + Start.ok + "件,请尽快完成付款");
74 | break;
75 | }
76 | } catch (IOException e) {
77 | e.printStackTrace();
78 | }
79 | if (submitOrder.contains("刷新太频繁了") || submitOrder.contains("抱歉,您访问的内容不存在")) {
80 | System.out.println("刷新太频繁了,您访问的内容不存在");
81 | continue;
82 | }
83 | JSONObject jsonObject = JSONObject.parseObject(submitOrder);
84 | String success = null;
85 | String message = null;
86 | if (jsonObject != null && jsonObject.get("success") != null) {
87 | success = jsonObject.get("success").toString();
88 | }
89 | if (jsonObject != null && jsonObject.get("message") != null) {
90 | message = jsonObject.get("message").toString();
91 | }
92 |
93 | if (success == "true") {
94 | System.out.println("抢购成功,请尽快完成付款");
95 | times++;
96 | } else {
97 | if (message != null) {
98 | System.out.println(message);
99 | } else if (submitOrder.contains("很遗憾没有抢到")) {
100 | System.out.println("很遗憾没有抢到,再接再厉哦");
101 | } else if (submitOrder.contains("抱歉,您提交过快,请稍后再提交订单!")) {
102 | System.out.println("抱歉,您提交过快,请稍后再提交订单!");
103 | } else if (submitOrder.contains("系统正在开小差,请重试~~")) {
104 | System.out.println("系统正在开小差,请重试~~");
105 | } else if (submitOrder.contains("您多次提交过快")) {
106 | System.out.println("您多次提交过快,请稍后再试");
107 | } else {
108 | System.out.println("获取用户订单信息失败");
109 | }
110 | }
111 | }
112 | }
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/com/jd/seckill/Start.java:
--------------------------------------------------------------------------------
1 | package com.jd.seckill;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.sun.webkit.network.CookieManager;
5 |
6 | import java.io.IOException;
7 | import java.net.CookieHandler;
8 | import java.net.URISyntaxException;
9 | import java.text.ParseException;
10 | import java.util.Scanner;
11 | import java.util.concurrent.Executors;
12 | import java.util.concurrent.PriorityBlockingQueue;
13 | import java.util.concurrent.ThreadPoolExecutor;
14 | import java.util.concurrent.TimeUnit;
15 |
16 | public class Start {
17 |
18 | final static String headerAgent = "User-Agent";
19 | // Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
20 | // Mozilla/5.0 (iPhone; CPU iPhone OS 15_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1
21 | final static String headerAgentArg = "JD4iPhone/10.1.6 CFNetwork/1312 Darwin/21.0.0";
22 | final static String Referer = "Referer";
23 | final static String RefererArg = "https://passport.jd.com/new/login.aspx";
24 | // 单手柄 100019378198 双手柄 100021367452 茅台 100012043978
25 | static String pid = new Scanner(System.in).nextLine();
26 | static String eid = "X";
27 | static String fp = "X";
28 | volatile static Integer ok = new Scanner(System.in).nextInt();
29 | static CookieManager manager = new CookieManager();
30 |
31 | public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException, ParseException {
32 | CookieHandler.setDefault(manager);
33 | Login.login();
34 | judgePruchase();
35 | ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 1000, TimeUnit.MILLISECONDS, new PriorityBlockingQueue(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
36 | for (int i = 0; i < 5; i++) {
37 | threadPoolExecutor.execute(new RushToPurchase());
38 | }
39 | new RushToPurchase().run();
40 | }
41 |
42 | public static void judgePruchase() throws IOException, ParseException, InterruptedException {
43 | JSONObject headers = new JSONObject();
44 | headers.put(Start.headerAgent, Start.headerAgentArg);
45 | headers.put(Start.Referer, Start.RefererArg);
46 | String str = HttpUrlConnectionUtil.get(headers, "https://item-soa.jd.com/getWareBusiness?skuId=" + pid);
47 | JSONObject shopDetail = JSONObject.parseObject(str);
48 | if (shopDetail.get("yuyueInfo") != null) {
49 | String buyDate = JSONObject.parseObject(shopDetail.get("yuyueInfo").toString()).get("buyTime").toString();
50 | String startDate = buyDate.split("-202")[0] + ":00";
51 | System.out.println("抢购时间为:" + startDate);
52 | Long startTime = HttpUrlConnectionUtil.dateToTime(startDate);
53 | while (true) {
54 | JSONObject jdTime = JSONObject.parseObject(HttpUrlConnectionUtil.get(headers, "https://api.m.jd.com/client.action?functionId=queryMaterialProducts&client=wh5"));
55 | Long serverTime = Long.valueOf(jdTime.get("currentTime2").toString());
56 | if (startTime >= serverTime) {
57 | System.out.println("正在等待抢购时间");
58 | Thread.sleep(300);
59 | } else {
60 | break;
61 | }
62 | }
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------