当前位置: 移动技术网 > IT编程>开发语言>Java > java实现京东秒杀功能分享 京东秒杀软件

java实现京东秒杀功能分享 京东秒杀软件

2019年07月22日  | 移动技术网IT编程  | 我要评论

简单介绍下功能

1.每隔一段时间(比如1分钟)在京东手机每日一秒杀页面提取产品(手机)链接。
http://sale.360buy.com/act/8vthfgr10cjmdyz.html#01
2.根据提取到得产品链接给后台发送数据,以便获取产品价格,描述,折扣,库存(是否有货)等信息。
3.根据得到的信息,进行判断。

若符合条件自动调用浏览器(前提是chrome加入环境变量,或者改代码将浏览器.exe路径加入代码,修改程序)打开产品订购页面。
4.其实也就解决了一个问题:不用自己频繁的刷新网页了,不用自己查看;
登陆,提交订单还得浏览器解决(貌似这几个功能点比较复杂,没做处理)

程序做的不太完善:
运行前需要修改几个地方:
1.环境变量:chrome 加入浏览器变量,以便调用。。或者自己修改源代码用其它方式打开。
2.活动中每个产品的价格信息需要设置。这个比较不好,必须修改源代码。
修改的地方在filter()这个函数里。
3.另外一个需要修改的地方是
hasstore(string skuidkey)

address="http://price.360buy.com/stocksoa/stockhandler.ashx?callback=getprovincestockcallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
这个地方的cityid=2800&areaid=...地里位置信息。这个没做处理。需要从手机产品页自己搞出来。
其实也比较简单。chrome+f12 ,修改“城市”,区域等信息后,会看到一个get请求发送到后台,这个链接里面包含了需要的信息。(http://price.360buy.com/stocksoa/stockhandler.ashx?callback=getprovincestockcallback&type=pcastock&skuid=64ebd0f20f593d95c72c6eed59b64658&provinceid=1&cityid=2805&areaid=2854)适当修改。

util.java

复制代码 代码如下:

package view.util;

import java.util.arraylist;

public class util {
 public static void print(object o){
  system.out.print(o);
 }
 public static void println(object o){
  if(null==o)
   system.out.println();
  else
  system.out.println(o);
 }
 public static arraylist<integer> toarraylist(int[] ints){
  if(ints.length==0)
  return null;
  arraylist<integer> al=new arraylist<integer>();
  for(int i=0;i<ints.length;i++){
   al.add(ints[i]);
  }
  return al;
 }
}

miaosha360buy.java

复制代码 代码如下:

package jingdong;

public class miaosha360buy {
 java.util.concurrent.countdownlatch t= new java.util.concurrent.countdownlatch(1);

 /**
  * @param args
  */
 public static void main(string[] args) {
  // todo auto-generated method stub
  system.out.println(thread.currentthread().getname() + "开始");
  miaosha360buy ms360=new miaosha360buy();
  new threadone360buy(ms360.t).start();
  while(true){
   try {
    ms360.t.await();
   } catch (interruptedexception e) {
    // todo auto-generated catch block
    e.printstacktrace();
   }
   try {
    thread.sleep(1000*60);//间隔1分钟调用一次?
   } catch (interruptedexception e) {
    // todo auto-generated catch block
    e.printstacktrace();
   }
   ms360.t=new java.util.concurrent.countdownlatch(1);
   new threadone360buy(ms360.t).start();
   system.out.println("new tread in while..");
  }
 }

}

miaosha360buy.java

复制代码 代码如下:

package jingdong;

public class miaosha360buy {
 java.util.concurrent.countdownlatch t= new java.util.concurrent.countdownlatch(1);

 /**
  * @param args
  */
 public static void main(string[] args) {
  // todo auto-generated method stub
  system.out.println(thread.currentthread().getname() + "开始");
  miaosha360buy ms360=new miaosha360buy();
  new threadone360buy(ms360.t).start();
  while(true){
   try {
    ms360.t.await();
   } catch (interruptedexception e) {
    // todo auto-generated catch block
    e.printstacktrace();
   }
   try {
    thread.sleep(1000*60);//间隔1分钟调用一次?
   } catch (interruptedexception e) {
    // todo auto-generated catch block
    e.printstacktrace();
   }
   ms360.t=new java.util.concurrent.countdownlatch(1);
   new threadone360buy(ms360.t).start();
   system.out.println("new tread in while..");
  }
 }

}

threadone360buy.java

复制代码 代码如下:

package jingdong;

import java.io.ioexception;
import java.util.arraylist;
import java.util.hashmap;
import java.util.list;
import java.util.regex.matcher;
import java.util.regex.pattern;

import org.apache.http.httpentity;
import org.apache.http.httpresponse;
import org.apache.http.client.clientprotocolexception;
import org.apache.http.client.methods.httpget;
import org.apache.http.impl.client.defaulthttpclient;
import org.apache.http.util.entityutils;
import org.jsoup.jsoup;
import org.jsoup.nodes.document;
import org.jsoup.nodes.element;
import org.jsoup.select.elements;

import view.util.util;

public class threadone360buy extends thread{
 java.util.concurrent.countdownlatch c;
 arraylist al;//记录秒杀产品页面
 float price=0.0f;//商品价格
 float discount=0.0f;//商品折扣

 //用于保存线程信息,在这个项目里用处不大
 private static list<thread> runningthreads = new arraylist<thread>();

 //这个是一个计数器(不太会用,线程这方面一直感觉是比较复杂的)
 public threadone360buy(java.util.concurrent.countdownlatch c) {
  this.c=c;
 }

 @override
 public void run() {
  regist(this);// 线程开始时注册
  // 打印开始标记
  system.out.println(thread.currentthread().getname() + "开始...");
  try {
   //抓取京东手机秒杀页面
   this.getmessage("http://sale.360buy.com/act/8vthfgr10cjmdyz.html#01");

  } catch (clientprotocolexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
   c.countdown();
  } catch (ioexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
   c.countdown();
  }
  c.countdown();
  unregist(this);// 线程结束时取消注册
  // 打印结束标记
  system.out.println(thread.currentthread().getname() + "结束.");
 }

 public void regist(thread t) {
  synchronized (runningthreads) {
   runningthreads.add(t);
  }
 }

 public void unregist(thread t) {
  synchronized (runningthreads) {
   runningthreads.remove(t);
  }
 }

 public static boolean hasthreadrunning() {
  // 通过判断runningthreads是否为空就能知道是否还有线程未执行完
  return (runningthreads.size() > 0);
 }
 /**
  * 从手机秒杀页面获取 prodcut链接,product skuid,skuidkey,price,store信息
  * @param url:手机秒杀页面
  * @throws clientprotocolexception
  * @throws ioexception
  */
 public void getmessage(string url) throws clientprotocolexception, ioexception{
  al=getmainurl(down(url));

  util.println(al);
  if(al.size()==0){
   c.countdown();
   system.exit(0);
   return;
  }

  for(int i=0;i<al.size();i++){
   stringbuffer sb=new stringbuffer();
   stringbuffer openurl = new stringbuffer();
   openurl.append("http://www.360buy.com/product/");
   openurl.append(al.get(i).tostring().subsequence(al.get(i).tostring().lastindexof('/')+1, al.get(i).tostring().lastindexof('.')));
   openurl.append(".html");
//   557673
   sb.append("http://d.360buy.com/fittinginfo/get?skuid=");
   sb.append(al.get(i).tostring().subsequence(al.get(i).tostring().lastindexof('/')+1, al.get(i).tostring().lastindexof('.')));
   sb.append("&callback=recommend.cbrecofittings");
   util.println(sb.tostring());
   //map中保存的是产品name,price,折扣信息
   util.println("al("+i+") down:"+sb.tostring());
   hashmap<string, string> hm=parseproduct(down(sb.tostring()));
   //用来匹配价格信息。匹配库存信息
   filter(hm,openurl.tostring());//过滤价格,如果条件符合就打开浏览器
  }
 }
 /**
  * 一个验证方法
  * @param hm 保存着价格信息
  * @param url 产品页面
  */
 public void filter(hashmap<string, string> hm,string url){//url既是产品页面
//  view.util.oencmd.openwinexe(null,url);
//  是不是应该先查看库存?
  string skuidkey=parseskuidkey(url);
  if(!hasstore(skuidkey)){
   util.println("-------------------------------------");
   util.println("没有库存了!");
   util.println("-------------------------------------");
   //减掉计数,以便主线程判断
   c.countdown();
   //应该结束子线程哦?
   return;
  }

  if(hm.get("skuid").equals("201602")){//判断//摩托罗拉skuid=201602
   //这里的价格是写死了,运行前得改过来才行。
   this.setprice(499.0f);
   //是不是应该打开控制台?
   if(float.parsefloat(hm.get("price"))<=this.getprice()){
    view.util.oencmd.openwinexe(null,url);
   }
  }else if(hm.get("skuid").equals("675647")){//天语skuid=675647
//   //这里的价格是写死了,运行前得改过来才行。
//   this.setprice(699.0f);
//   //是不是应该打开控制台?
//   if(float.parsefloat(hm.get("price"))<=this.getprice()){
//    view.util.oencmd.openwinexe(null,url);
//   }
  }

 }
 /**
  * 解析了产品页面中name,skuid,price信息
  * @param doc
  * @return
  */
 public static hashmap<string, string> parseproduct(document doc){
  string text=doc.text();
  string docc=text.substring(text.indexof("master")+9,text.indexof("fittings")-3).replaceall("[\\s]", "");
  string[] ss=docc.split(",");
  hashmap<string, string> hm=new hashmap<string, string>();
  for(string it: ss){
   string string=it.replaceall("\"", "");
   if(string.contains("\\u"))
   string=unicodedecode(string);

   string[] str=string.split(":");
   hm.put(str[0], str[1]);
  }
  util.println(hm);
  return hm;
 }
 /**
  * 处理unicode字符,转换成显示字符(汉字),不太通用
  * @param it: \u6a5d
  * @return
  */
 public static string unicodedecode(string it){//有个缺点,就是前面的字符无法去掉
  util.println(it);
  string regex="(\\\\u[0-9a-f]{4})";
  pattern pt= pattern.compile(regex);
  matcher mc;
  stringbuffer sb;
  stringbuffer sba=new stringbuffer();
  mc=pt.matcher(it);
  while(mc.find()){
   sb=new stringbuffer();
    mc.appendreplacement(sba,sb.append((char )integer.parseint((mc.group(1).substring(2)), 16)).tostring());
  }
  return sba.tostring();
 }
 /**
  * 返回文档对象(下载内容)
  * @param url 下载页面
  * @return
  * @throws clientprotocolexception
  * @throws ioexception
  */
 public static document down(string url) throws clientprotocolexception, ioexception{
  document doc = null;
  defaulthttpclient httpclient=new defaulthttpclient();
  util.println("download:"+url);
  httpget get=new httpget(url);
  httpresponse response;
  response = httpclient.execute(get);
  httpentity entity = response.getentity();
  doc = jsoup.parse(entity.getcontent(), "utf-8","");
  //释放资源
  entityutils.consume(entity);
  //关闭连接
  httpclient.getconnectionmanager().shutdown();
  return doc;
 }
 /**
  * 加入了编码控制信息
  * @param url 待下载页面
  * @param code 编码
  * @return
  * @throws clientprotocolexception
  * @throws ioexception
  */
 public static document down(string url,string code) throws clientprotocolexception, ioexception{
  document doc = null;
  defaulthttpclient httpclient=new defaulthttpclient();
  util.println("download:"+url);
  httpget get=new httpget(url);
  httpresponse response;
  response = httpclient.execute(get);
  httpentity entity = response.getentity();
  doc = jsoup.parse(entity.getcontent(), code,"");
  //释放资源
  entityutils.consume(entity);
  //关闭连接
  httpclient.getconnectionmanager().shutdown();
  return doc;
 }
 /**
  * 用来解析 秒杀页面中的产品(收集)链接
  * @param doc
  * @return
  */
 public static arraylist<string> getmainurl(document doc){
  if(doc.equals("")||doc==null)
   return null;
  try {
   thread.sleep(50);
  } catch (interruptedexception e1) {
   // todo auto-generated catch block
   e1.printstacktrace();
  }
  arraylist<string> urls=new arraylist<string>();
  string rule="map[name=map] >area[href~=product]";
  /**
   * 开始解析
   */
  elements elements=doc.select(rule);
  for (element e : elements) {
//   util.println(e.absurl("abs:href"));
   urls.add(e.absurl("abs:href"));
  }
  return urls;
 }
 /**
  * 获取skuidkey,用于查询商品库存信息
  * @param url
  * @return
  */
 public static string parseskuidkey(string url){
  document doc=null;
  try {
   doc=down(url,"gb2312");
  } catch (clientprotocolexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  } catch (ioexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  }
//  util.println(doc.select("script"));
  string text = null;
  for(element e : doc.select("script")){
   if(e.data().contains("skuidkey:")){
    text=e.data();
    break;
   }
  }
  //skuidkey:'7d45919ea8242511daa5cc7c6d7b351c'
  text=text.substring(text.indexof("skuidkey:")+10, text.indexof("skuidkey:")+42);
  util.println("---------------------------------");
  util.println(text);
  return text;
 }
 /**
  * 查看库存信息
  * @param skuidkey
  * @return
  */
 public static boolean hasstore(string skuidkey){//这个地方没有处理,直接提取浏览器中的信息
  string address = null;
  boolean hasstore=false;
  if(skuidkey!=null && !"".equals(skuidkey))
  address="http://price.360buy.com/stocksoa/stockhandler.ashx?callback=getprovincestockcallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
  else{
   util.println("解析skuidkey错误");
  }
  try {
   if(parsestore(down(address))){
    hasstore=true;
   }
  } catch (clientprotocolexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  } catch (ioexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  }
  return hasstore;
 }
/* if(array[1]=="34"||array[1]=="18"){
 changecart(false);
djdarea.stockinfodom.html("<strong class='store-over'>无货</strong>");
}
else if(array[1]=="0"){
changecart(false);
djdarea.stockinfodom.html("<strong class='store-over'>无货</strong>");
}
else if(array[2]=="0"&&array[4]!="2"){
changecart(false);
djdarea.stockinfodom.html("很抱歉,该商品无法送至您选择的区域");
}
else if(array[1]=="33"||array[1]=="5"){
changecart(true);
djdarea.stockinfodom.html("<strong>现货</strong>"+(array[4]=="1"?",该区域"+(array[3]=="0"?"不":"")+"支持货到付款":"")+cashdesc);
}
else if(array[1]=="36"){
changecart(true);
djdarea.stockinfodom.html("<strong>预订</strong>"+(array[4]=="1"?",该区域"+(array[3]=="0"?"不":"")+"支持货到付款":"")+cashdesc);
}
else if(array[1]=="39"){
changecart(true);
djdarea.stockinfodom.html("<strong>在途</strong>"+(array[4]=="1"?",该区域"+(array[3]=="0"?"不":"")+"支持货到付款":"")+cashdesc);
}
else if(array[1]=="40"){
changecart(true);
djdarea.stockinfodom.html("<strong>可配货</strong>"+(array[4]=="1"?",该区域"+(array[3]=="0"?"不":"")+"支持货到付款":"")+cashdesc);
}
 */
 /**
  * 解析库存信息
  * @param doc
  * @return
  */
 public static boolean parsestore(document doc){
  string text=doc.text();
  string docc=text.substring(text.indexof("-")-1,text.lastindexof(",")-1);
  util.println(docc);
  string[] store=docc.split("-");
  if(store[1].equals("34") || store[1].equals("18")){
   //无货
   util.println("此地无货");
   return false;
  }else if(store[1].equals("33") || store[1].equals("5")){
   //现货
   util.println("此地现货");
   return true;
  }
  util.println(store[1]);
  return false;
 }
 //几个bean方法
 public float getprice() {
  return price;
 }
 public void setprice(float price) {
  this.price = price;
 }
 public float getdiscount() {
  return discount;
 }
 public void setdiscount(float discount) {
  this.discount = discount;
 }
 

}

oencmd.java

复制代码 代码如下:

package view.util;

public class oencmd {
// public static void main(string[] args) {
////    openwinexe(null);
//    openexe(null,"http://www.baidu.com");
//    }
    //用 java 调用windows系统的exe文件,比如notepad,calc之类
    public static void openwinexe(string command,string url) {
     if(command==null ||command.equals("")){
      command = "chrome "+url;
     }
    runtime rn = runtime.getruntime();
    process p = null;
    try {

    p = rn.exec(command);
    } catch (exception e) {
    system.out.println("error win exec!");
    }
    }
    //调用其他的可执行文件,例如:自己制作的exe,或是 下载 安装的软件.
    public static void openexe(string pathandname,string url) {
     if(pathandname==null || pathandname.equals("")){
      pathandname="c:\\users\\administrator\\appdata\\local\\google\\chrome\\application\\chrome.exe";
     }
     if(url!=null && !url.equals("")){
      pathandname+=" ";
      pathandname+=url;
     }
    runtime rn = runtime.getruntime();
    process p = null;
    try {
    p = rn.exec(pathandname);
    } catch (exception e) {
    system.out.println("error exec!");
    }
    }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网