├── 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 | --------------------------------------------------------------------------------