抢购 多线程

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)适当修改。

 

源码如下:

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;

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;


public class ThreadOne extends Thread {
    private static List<Thread> runningThreads = new ArrayList<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 ThreadOne(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("很抱歉,该商品无法送至您选择的区域");

}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;
    }
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值