github地址:https://github.com/zhao458114067/Jd-Pruchase-Kill
github已被京东强制关闭…
1、首先是Start.class
主类:
package com.zx.jdkill.test;
import com.alibaba.fastjson.JSONObject;
import com.sun.webkit.network.CookieManager;
import java.io.IOException;
import java.net.CookieHandler;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author: zhaoxu
* @date: 2021/1/8 20:59
*/
public class Start {
final static String headerAgent = "User-Agent";
final static String headerAgentArg = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36";
final static String Referer = "Referer";
final static String RefererArg = "https://passport.jd.com/new/login.aspx";
//商品id
static String pid = "30425081079";
//eid
static String eid = "W2HEXZSRULGOBXAMFF6J44UTIGCP5QGKRQO5M7KZHYUAU7RT2JBTXRG2ZNRUWHKYX2PHNKRJI2KOM7BZIZ2V3F3C64";
//fp
static String fp = "4ce08fcab2f99f47724c9c7cdf771d9f";
//抢购数量
volatile static Integer ok = 2;
static CookieManager manager = new CookieManager();
public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException, ParseException {
CookieHandler.setDefault(manager);
//获取venderId
// String shopDetail = util.get(null, "https://item.jd.com/" + RushToPurchase.pid + ".html");
// String venderID = shopDetail.split("isClosePCShow: false,\n" +
// " venderId:")[1].split(",")[0];
// RushToPurchase.venderId = venderID;
//登录
Login.Login();
//判断是否开始抢购
judgePruchase();
//开始抢购
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 1000, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
for (int i = 0; i < 5; i++) {
threadPoolExecutor.execute(new RushToPurchase());
}
new RushToPurchase().run();
}
public static void judgePruchase() throws IOException, ParseException, InterruptedException {
//获取开始时间
JSONObject headers = new JSONObject();
headers.put(Start.headerAgent, Start.headerAgentArg);
headers.put(Start.Referer, Start.RefererArg);
JSONObject shopDetail = JSONObject.parseObject(HttpUrlConnectionUtil.get(headers, "https://item-soa.jd.com/getWareBusiness?skuId=" + pid));
if (shopDetail.get("yuyueInfo") != null) {
String buyDate = JSONObject.parseObject(shopDetail.get("yuyueInfo").toString()).get("buyTime").toString();
String startDate = buyDate.split("-202")[0] + ":00";
Long startTime = HttpUrlConnectionUtil.dateToTime(startDate);
//开始抢购
while (true) {
//获取京东时间
JSONObject jdTime = JSONObject.parseObject(HttpUrlConnectionUtil.get(headers, "https://a.jd.com//ajax/queryServerData.html"));
Long serverTime = Long.valueOf(jdTime.get("serverTime").toString());
if (startTime >= serverTime) {
System.out.println("正在等待抢购时间");
Thread.sleep(300);
} else {
break;
}
}
}
}
}
2、HttpUrlConnectionUtil.class
工具类
package com.zx.jdkill.test;
import com.alibaba.fastjson.JSONObject;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
/**
* @author: zhaoxu
* @date: 2021/1/5 22:26
*/
public class HttpUrlConnectionUtil {
/**
* get请求
*
* @param headers 请求头,可为空
* @param url
* @return
* @throws IOException
*/
public static String get(JSONObject headers, String url) throws IOException {
String response = "";
HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
httpURLConnection.setRequestMethod("GET");
if (headers != null) {
Iterator<String> iterator = headers.keySet().iterator();
while (iterator.hasNext()) {
String headerName = iterator.next();
httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
}
}
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200) {
InputStream inputStream = httpURLConnection.getInputStream();
byte[] buffer;
buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
response = response + new String(buffer, 0, length, "UTF-8");
}
httpURLConnection.disconnect();
}
return response;
}
/**
* post请求
*
* @param headers 请求头,可为空
* @param url
* @param params post请求体,可为空
* @return
* @throws IOException
*/
public static String post(JSONObject headers, String url, JSONObject params) throws IOException {
String response = "";
HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
httpURLConnection.setRequestMethod("POST");
if (headers != null) {
Iterator<String> iterator = headers.keySet().iterator();
while (iterator.hasNext()) {
String headerName = iterator.next();
httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
}
}
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
if (params != null) {
httpURLConnection.getOutputStream().write(params.toJSONString().getBytes("UTF-8"));
}
httpURLConnection.getInputStream();
if (httpURLConnection.getResponseCode() == 200) {
InputStream inputStream = httpURLConnection.getInputStream();
byte[] buffer;
buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
response = response + new String(buffer, 0, length, "UTF-8");
}
httpURLConnection.disconnect();
}
httpURLConnection.disconnect();
return response;
}
/**
* 获取并保存二维码
*
* @param headers
* @param url
* @return
* @throws IOException
*/
public static String getQCode(JSONObject headers, String url) throws IOException {
String response = "";
HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(url).openConnection());
httpURLConnection.setRequestMethod("GET");
if (headers != null) {
Iterator<String> iterator = headers.keySet().iterator();
while (iterator.hasNext()) {
String headerName = iterator.next();
httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
}
}
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200) {
InputStream inputStream = httpURLConnection.getInputStream();
OutputStream outputStream = new FileOutputStream("QCode.png");
byte[] buffer;
int length;
buffer = new byte[1024];
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
response = response + new String(buffer, 0, length, "UTF-8");
}
outputStream.close();
httpURLConnection.disconnect();
}
return response;
}
/**
* date字符串转时间戳
*
* @param date
* @return
*/
public static Long dateToTime(String date) throws ParseException {
SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date data = sdfTime.parse(date);
Long time = data.getTime();
return time;
}
/**
* time时间戳转Date
*
* @param time
* @return
*/
public static Date timeToDate(String time) {
SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdfTime.format(Long.valueOf(time));
try {
Date date = sdfTime.parse(str);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
public static ArrayList<String> ips() throws IOException {
String path = "http://api.xiequ.cn/VAD/GetIp.aspx?act=get&num=1&time=30&plat=1&re=0&type=0&so=1&ow=1&spl=1&addr=&db=1";// 要获得html页面内容的地址
URL url = new URL(path);// 创建url对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 打开连接
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
conn.setRequestProperty("contentType", "GBK"); // 设置url中文参数编码
conn.setConnectTimeout(5 * 1000);// 请求的时间
conn.setRequestMethod("GET");// 请求方式
InputStream inStream = conn.getInputStream();
// readLesoSysXML(inStream);
BufferedReader in = new BufferedReader(new InputStreamReader(inStream, "GBK"));
StringBuffer buffer = new StringBuffer();
ArrayList<String> ipp = new ArrayList<String>();
String line = "";
// 读取获取到内容的最后一行,写入
while ((line = in.readLine()) != null) {
buffer.append(line);
ipp.add(line);
System.out.println(line);
}
String str = buffer.toString();
// JSONObject json1 = JSONObject.parseObject(str);
// JSONArray jsons = JSONArray.parseArray(json1.get("data").toString());
// for(Object json:jsons){
// JSONObject ips = JSONObject.parseObject(json.toString());
// String ip = ips.get("IP").toString();
// System.out.println(ip);
// ipp.add(ip);
// }
return ipp;
}
}
3、这里正是开始,Login.class:
package com.zx.jdkill.test;
import com.alibaba.fastjson.JSONObject;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author: zhaoxu
* @date: 2021/1/9 18:59
*/
public class Login {
static String venderId = "";
static Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>(16);
static String ticket = "";
public static void Login() throws IOException, URISyntaxException, InterruptedException {
JSONObject headers = new JSONObject();
headers.put(Start.headerAgent, Start.headerAgentArg);
headers.put(Start.Referer, Start.RefererArg);
//获取二维码
Long now = System.currentTimeMillis();
HttpUrlConnectionUtil.getQCode(headers, "https://qr.m.jd.com/show?appid=133&size=147&t=" + now);
//打开二维码
Runtime.getRuntime().exec("cmd /c QCode.png");
URI url = new URI("https://qr.m.jd.com/show?appid=133&size=147&t=" + now);
Map<String, List<String>> stringListMap = new HashMap<String, List<String>>();
stringListMap = Start.manager.get(url, requestHeaders);
List cookieList = stringListMap.get("Cookie");
String cookies = cookieList.get(0).toString();
String token = cookies.split("wlfstk_smdl=")[1];
headers.put("Cookie", cookies);
//判断是否扫二维码
while (true) {
String checkUrl = "https://qr.m.jd.com/check?appid=133&callback=jQuery" + (int) ((Math.random() * (9999999 - 1000000 + 1)) + 1000000) + "&token=" + token + "&_=" + System.currentTimeMillis();
String qrCode = HttpUrlConnectionUtil.get(headers, checkUrl);
if (qrCode.indexOf("二维码未扫描") != -1) {
System.out.println("二维码未扫描,请扫描二维码登录");
} else if (qrCode.indexOf("请手机客户端确认登录") != -1) {
System.out.println("请手机客户端确认登录");
} else {
ticket = qrCode.split("\"ticket\" : \"")[1].split("\"\n" +
"}\\)")[0];
System.out.println("已完成二维码扫描登录");
close();
break;
}
Thread.sleep(3000);
}
//验证,获取cookie
String qrCodeTicketValidation = HttpUrlConnectionUtil.get(headers, "https://passport.jd.com/uc/qrCodeTicketValidation?t=" + ticket);
stringListMap = Start.manager.get(url, requestHeaders);
cookieList = stringListMap.get("Cookie");
cookies = cookieList.get(0).toString();
headers.put("Cookie", cookies);
}
public static void close() throws IOException, InterruptedException {
// 通过窗口标题获取窗口句柄
WinDef.HWND hWnd;
final User32 user32 = User32.INSTANCE;
user32.EnumWindows(new WinUser.WNDENUMPROC() {
@Override
public boolean callback(WinDef.HWND hWnd, Pointer arg1) {
char[] windowText = new char[512];
user32.GetWindowText(hWnd, windowText, 512);
String wText = Native.toString(windowText);
// get rid of this if block if you want all windows regardless of whether
// or not they have text
if (wText.isEmpty()) {
return true;
}
if (wText.contains("照片")) {
hWnd = User32.INSTANCE.FindWindow(null, wText);
WinDef.LRESULT lresult = User32.INSTANCE.SendMessage(hWnd, 0X10, null, null);
}
return true;
}
}, null);
}
}
4、抢购的线程RushToPurchase.class
package com.zx.jdkill.test;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author: zhaoxu
* @date: 2021/1/8 20:51
*/
public class RushToPurchase implements Runnable {
//请求头
volatile static Integer times = 0;
static Map<String, List<String>> stringListMap = new HashMap<String, List<String>>();
public void run() {
JSONObject headers = new JSONObject();
while (times < Start.ok) {
//获取ip,使用的是免费的 携趣代理 ,不需要或者不会用可以注释掉
setIpProxy();
headers.put(Start.headerAgent, Start.headerAgentArg);
headers.put(Start.Referer, Start.RefererArg);
//抢购
String gate = null;
try {
gate = HttpUrlConnectionUtil.get(headers, "https://cart.jd.com/gate.action?pcount=1&ptype=1&pid=" + Start.pid);
} catch (IOException e) {
e.printStackTrace();
}
//订单信息
stringListMap.clear();
try {
stringListMap = Start.manager.get(new URI("https://trade.jd.com/shopping/order/getOrderInfo.action"), stringListMap);
} catch (URISyntaxException e) {
e.printStackTrace();
}
List<String> cookie = stringListMap.get("Cookie");
headers.put("Cookie", cookie.get(0).toString());
try {
String orderInfo = HttpUrlConnectionUtil.get(headers, "https://trade.jd.com/shopping/order/getOrderInfo.action");
} catch (IOException e) {
e.printStackTrace();
}
//提交订单
JSONObject subData = new JSONObject();
headers = new JSONObject();
subData.put("overseaPurchaseCookies", "");
subData.put("vendorRemarks", "[]");
subData.put("submitOrderParam.sopNotPutInvoice", "false");
subData.put("submitOrderParam.ignorePriceChange", "1");
subData.put("submitOrderParam.btSupport", "0");
subData.put("submitOrderParam.isBestCoupon", "1");
subData.put("submitOrderParam.jxj", "1");
subData.put("submitOrderParam.trackID", Login.ticket);
subData.put("submitOrderParam.eid", Start.eid);
subData.put("submitOrderParam.fp", Start.fp);
subData.put("submitOrderParam.needCheck", "1");
headers.put("Referer", "http://trade.jd.com/shopping/order/getOrderInfo.action");
headers.put("origin", "https://trade.jd.com");
headers.put("Content-Type", "application/json");
headers.put("x-requested-with", "XMLHttpRequest");
headers.put("upgrade-insecure-requests", "1");
headers.put("sec-fetch-user", "?1");
stringListMap.clear();
try {
stringListMap = Start.manager.get(new URI("https://trade.jd.com/shopping/order/getOrderInfo.action"), stringListMap);
} catch (URISyntaxException e) {
e.printStackTrace();
}
cookie = stringListMap.get("Cookie");
headers.put("Cookie", cookie.get(0).toString());
String submitOrder = null;
try {
if (times < Start.ok) {
submitOrder = HttpUrlConnectionUtil.post(headers, "https://trade.jd.com/shopping/order/submitOrder.action", null);
} else {
System.out.println("已抢购" + Start.ok + "件,请尽快完成付款");
break;
}
} catch (IOException e) {
e.printStackTrace();
}
if (submitOrder.contains("刷新太频繁了") || submitOrder.contains("抱歉,您访问的内容不存在")) {
System.out.println("刷新太频繁了,您访问的内容不存在");
continue;
}
JSONObject jsonObject = JSONObject.parseObject(submitOrder);
String success = null;
String message = null;
if (jsonObject != null && jsonObject.get("success") != null) {
success = jsonObject.get("success").toString();
}
if (jsonObject != null && jsonObject.get("message") != null) {
message = jsonObject.get("message").toString();
}
if (success == "true") {
System.out.println("抢购成功,请尽快完成付款");
times++;
} else {
if (message != null) {
System.out.println(message);
} else if (submitOrder.contains("很遗憾没有抢到")) {
System.out.println("很遗憾没有抢到,再接再厉哦");
} else if (submitOrder.contains("抱歉,您提交过快,请稍后再提交订单!")) {
System.out.println("抱歉,您提交过快,请稍后再提交订单!");
} else if (submitOrder.contains("系统正在开小差,请重试~~")) {
System.out.println("系统正在开小差,请重试~~");
} else if (submitOrder.contains("您多次提交过快")) {
System.out.println("您多次提交过快,请稍后再试");
} else {
System.out.println("获取用户订单信息失败");
}
}
}
}
public static void setIpProxy() {
String ip = null;
try {
ip = HttpUrlConnectionUtil.ips().get(0);
} catch (IOException e) {
e.printStackTrace();
}
String[] r1 = ip.split(":");
System.out.println(ip);
System.getProperties().setProperty("http.proxyHost", r1[0]);
System.getProperties().setProperty("http.proxyPort", r1[1]);
System.err.println(r1[0] + ":" + r1[1]);
}
}
5、pom依赖,好像没用到httpcomponents
:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>