您的位置:首页 > 其它

抢购 多线程

2015-10-26 13:51 197 查看
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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: