Introduce brevemente las funciones.
1. Extraiga el enlace del producto (teléfono móvil) de la página de venta flash diaria de JD Mobile de vez en cuando (por ejemplo, 1 minuto).
http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01
2. Envíe datos al backend según el enlace del producto extraído para obtener el precio del producto, la descripción, el descuento, el inventario (si está en stock) y otra información.
3. Emitir juicios basados en la información obtenida.
Si se cumplen las condiciones, se llamará automáticamente al navegador (siempre que se agregue Chrome a la variable de entorno o se cambie el código para agregar la ruta browser.exe al código y se modifique el programa) para abrir el pedido de productos. página.
4. De hecho, esto resuelve un problema: ya no es necesario actualizar la página web con frecuencia ni comprobarla usted mismo;
El inicio de sesión y el envío de pedidos deben solucionarse mediante el navegador (parece que estos puntos funcionales son más complicados y no se han procesado)
El programa no es perfecto:
Hay varios lugares que deben modificarse antes de ejecutar:
1. Variables de entorno: Chrome agrega variables del navegador para facilitar las llamadas. . O modifique el código fuente usted mismo y ábralo de otras formas.
2. Es necesario establecer la información de precios de cada producto de la actividad. Esto no es bueno, hay que modificar el código fuente.
La modificación está en la función filter().
3. Otro lugar que necesita ser modificado es
hasStore (cadena skuidkey)
dirección="http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
La cityid=2800&areaid=...información de ubicación de este lugar. Esto no fue procesado. Debe averiguarlo usted mismo desde la página del producto del teléfono móvil.
En realidad, es relativamente simple. Chrome + F12, después de modificar la "ciudad", la región y otra información, verá una solicitud de obtención enviada en segundo plano. Este enlace contiene la información requerida. (http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid=64EBD0F20F593D95C72C6EED59B64658&provinceid=1&cityid=2805&areaid=2854) Modificar adecuadamente.
util.java
Copie el código de código de la siguiente manera:
vista del paquete.Util;
importar java.util.ArrayList;
clase pública Util {
impresión pública vacía estática (Objeto o) {
Sistema.out.print(o);
}
public static void println(Objeto o){
si(nulo==o)
System.out.println();
demás
System.out.println(o);
}
pública estática ArrayList<Integer> toArrayList(int[] enteros){
si(ints.longitud==0)
devolver nulo;
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=0;i<ints.length;i++){
al.add(ints[i]);
}
devolver al;
}
}
Miaosha360buy.java
Copie el código de código de la siguiente manera:
paquete jingdong;
clase pública Miaosha360buy {
java.util.concurrent.CountDownLatch t= nuevo java.util.concurrent.CountDownLatch(1);
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
// TODO Código auxiliar de método generado automáticamente
System.out.println(Thread.currentThread().getName() + "inicio");
Miaosha360buy ms360=nuevo Miaosha360buy();
nuevo ThreadOne360buy(ms360.t).start();
mientras (verdadero) {
intentar {
ms360.t.await();
} captura (Excepción interrumpida e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
intentar {
Thread.sleep(1000*60); // ¿Llamado cada 1 minuto?
} captura (Excepción interrumpida e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
ms360.t=nuevo java.util.concurrent.CountDownLatch(1);
nuevo ThreadOne360buy(ms360.t).start();
System.out.println("Nueva pisada mientras...");
}
}
}
Miaosha360buy.java
Copie el código de código de la siguiente manera:
paquete jingdong;
clase pública Miaosha360buy {
java.util.concurrent.CountDownLatch t= nuevo java.util.concurrent.CountDownLatch(1);
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
// TODO Código auxiliar de método generado automáticamente
System.out.println(Thread.currentThread().getName() + "inicio");
Miaosha360buy ms360=nuevo Miaosha360buy();
nuevo ThreadOne360buy(ms360.t).start();
mientras (verdadero) {
intentar {
ms360.t.await();
} captura (Excepción interrumpida e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
intentar {
Thread.sleep(1000*60); // ¿Llamado cada 1 minuto?
} captura (Excepción interrumpida e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
ms360.t=nuevo java.util.concurrent.CountDownLatch(1);
nuevo ThreadOne360buy(ms360.t).start();
System.out.println("Nueva pisada mientras...");
}
}
}
ThreadOne360buy.java
Copie el código de código de la siguiente manera:
paquete jingdong;
importar java.io.IOException;
importar java.util.ArrayList;
importar java.util.HashMap;
importar java.util.List;
importar java.util.regex.Matcher;
importar java.util.regex.Pattern;
importar org.apache.http.HttpEntity;
importar org.apache.http.HttpResponse;
importar org.apache.http.client.ClientProtocolException;
importar org.apache.http.client.methods.HttpGet;
importar org.apache.http.impl.client.DefaultHttpClient;
importar org.apache.http.util.EntityUtils;
importar org.jsoup.Jsoup;
importar org.jsoup.nodes.Document;
importar org.jsoup.nodes.Element;
importar org.jsoup.select.Elements;
importar vista.Util.Util;
la clase pública ThreadOne360buy extiende Thread{
java.util.concurrent.CountDownLatchc;
ArrayList al;//Registrar página de producto de venta flash
precio flotante=0.0f;//precio del producto
descuento flotante=0.0f;//Descuento de producto
//Se utiliza para guardar información del hilo, no es muy útil en este proyecto
Lista estática privada<Thread> runningThreads = new ArrayList<Thread>();
//Este es un contador (no es muy bueno usándolo, los hilos siempre se han sentido más complicados)
público ThreadOne360buy(java.util.concurrent.CountDownLatch c) {
esto.c=c;
}
@Anular
ejecución pública vacía() {
registrarse(this);//Registrarse cuando comience el hilo
// imprimir etiqueta de inicio
System.out.println(Thread.currentThread().getName() + "Inicio...");
intentar {
// Vea la página de venta flash de teléfonos móviles de Jingdong
this.getMessage("http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01");
} captura (ClientProtocolException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
c.countDown();
} captura (IOException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
c.countDown();
}
c.countDown();
unRegist(this);//Dar de baja cuando finalice el hilo
// imprimir etiqueta final
System.out.println(Thread.currentThread().getName() + "Fin.");
}
registro público vacío (hilo t) {
sincronizado (runningThreads) {
runningThreads.add(t);
}
}
anulación del registro público nulo (hilo t) {
sincronizado (runningThreads) {
ejecutandoThreads.remove(t);
}
}
público estático booleano hasThreadRunning() {
// Al juzgar si runningThreads está vacío, puede saber si hay subprocesos que aún no se han ejecutado.
retorno (runningThreads.size() > 0);
}
/**
* Obtenga el enlace del producto, el skuid del producto, el skuidkey, el precio y la información de la tienda desde la página de venta flash móvil
* @param url: página de venta flash móvil
* @throws ClientProtocolException
* @throwsIOException
*/
public void getMessage (String url) lanza ClientProtocolException, IOException {
al=getMainUrl(abajo(url));
Util.println(al);
si(al.tamaño()==0){
c.countDown();
Sistema.salir(0);
devolver;
}
para(int i=0;i<al.size();i++){
StringBuffer sb=nuevo StringBuffer();
StringBuffer openUrl = nuevo 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=Recomendar.cbRecoFittings");
Util.println(sb.toString());
//Lo que se guarda en el mapa es el nombre del producto, el precio y la información de descuento.
Util.println("Al("+i+") abajo:"+sb.toString());
HashMap<String, String> hm=parseProduct(down(sb.toString()));
//Se utiliza para hacer coincidir la información de precios. Coincidir con la información del inventario
filter(hm,openUrl.toString());//Filtrar el precio y abrir el navegador si se cumplen las condiciones
}
}
/**
* Un método de verificación
* @param hm contiene información de precios
* @param URL de la página del producto
*/
filtro de vacío público (HashMap<String, String> hm,String url){//url es la página del producto
//view.Util.oenCMD.openWinExe(null,url);
//¿Deberíamos comprobar el inventario primero?
Cadena skuidkey=parseSkuidkey(url);
si(!hasStore(skuidkey)){
Util.println("----------------------------------------");
Util.println("¡Agotado!");
Util.println("----------------------------------------");
//Disminuye el conteo para que el hilo principal pueda juzgar
c.countDown();
// ¿Deberíamos finalizar el hilo secundario?
devolver;
}
if(hm.get("skuid").equals("201602")){//Juicio//Motorola skuid=201602
// El precio aquí está codificado y debe cambiarse antes de ejecutarse.
this.setPrice(499.0f);
//¿Se debe abrir la consola?
if(Float.parseFloat(hm.get("precio"))<=this.getPrice()){
view.Util.oenCMD.openWinExe(nulo,url);
}
}else if(hm.get("skuid").equals("675647")){//Tianyu skuid=675647
//// El precio aquí está codificado y debe cambiarse antes de ejecutarse.
//this.setPrice(699.0f);
////¿Se debe abrir la consola?
//if(Float.parseFloat(hm.get("precio"))<=this.getPrice()){
//view.Util.oenCMD.openWinExe(null,url);
//}
}
}
/**
* Analizado el nombre, skuid, información de precio en la página del producto.
* @paramdoc
* @devolver
*/
HashMap estático público<String, String> parseProduct(Documento doc){
Texto de cadena=doc.text();
String docc=text.substring(text.indexOf("master")+9,text.indexOf("accesorios")-3).replaceAll("[//s]", "");
Cadena[] ss=docc.split(",");
HashMap<Cadena, Cadena> hm=nuevo HashMap<Cadena, Cadena>();
para(Cadenarlo: ss){
Cadena cadena=it.replaceAll("/"", "");
si(cadena.contiene("//u"))
cadena=unicodeDecode(cadena);
Cadena[] str=string.split(":");
hm.put(cadena[0], cadena[1]);
}
Util.println(hm);
volver mmm;
}
/**
* Procese caracteres Unicode y conviértalos en caracteres para mostrar (caracteres chinos), lo cual no es muy versátil.
* @param it: /u6a5d
* @devolver
*/
public static String unicodeDecode(String it){//Una desventaja es que los caracteres anteriores no se pueden eliminar
Util.println(eso);
String regex="(////u[0-9a-f]{4})";
Patrón pt= Pattern.compile(regex);
Emparejador mc;
StringBuffer sb;
StringBuffer sba=nuevo StringBuffer();
mc=pt.matcher(es);
mientras(mc.find()){
sb=nuevo StringBuffer();
mc.appendReplacement(sba,sb.append((char )Integer.parseInt((mc.group(1).substring(2)), 16)).toString());
}
devolver sba.toString();
}
/**
* Objeto de documento de devolución (descargar contenido)
* Página de descarga de URL @param
* @devolver
* @throws ClientProtocolException
* @throwsIOException
*/
Documento estático público inactivo (URL de cadena) arroja ClientProtocolException, IOException {
Documento doc = nulo;
DefaultHttpClient httpClient=nuevo DefaultHttpClient();
Util.println("Descargar:"+url);
HttpGet get=nuevo HttpGet(url);
respuesta HttpResponse;
respuesta = httpClient.execute(get);
entidad HttpEntity = respuesta.getEntity();
doc = Jsoup.parse(entity.getContent(), "utf-8","");
//Liberar recursos
EntityUtils.consume(entidad);
//Cierra la conexión
httpClient.getConnectionManager().shutdown();
devolver documento;
}
/**
* Información de control de codificación agregada.
* @param página URL para descargar
* Codificación de código @param
* @devolver
* @throws ClientProtocolException
* @throwsIOException
*/
Documento estático público inactivo (URL de cadena, código de cadena) arroja ClientProtocolException, IOException {
Documento doc = nulo;
DefaultHttpClient httpClient=nuevo DefaultHttpClient();
Util.println("Descargar:"+url);
HttpGet get=nuevo HttpGet(url);
respuesta HttpResponse;
respuesta = httpClient.execute(get);
entidad HttpEntity = respuesta.getEntity();
doc = Jsoup.parse(entity.getContent(), código,"");
//Liberar recursos
EntityUtils.consume(entidad);
//Cierra la conexión
httpClient.getConnectionManager().shutdown();
devolver documento;
}
/**
* Se utiliza para analizar enlaces de productos (colección) en páginas de venta flash.
* @paramdoc
* @devolver
*/
ArrayList público estático<Cadena> getMainUrl(Documento doc){
si(doc.equals("")||doc==null)
devolver nulo;
intentar {
Hilo.dormir(50);
} captura (Excepción interrumpida e1) {
// TODO Bloque de captura generado automáticamente
e1.printStackTrace();
}
ArrayList<String> urls=new ArrayList<String>();
String rule="mapa[nombre=Mapa] >área[href~=producto]";
/**
* Iniciar análisis
*/
Elementos elementos=doc.select(regla);
para (Elemento e: elementos) {
//Util.println(e.absUrl("abs:href"));
urls.add(e.absUrl("abs:href"));
}
URL de retorno;
}
/**
* Obtenga skuidkey para consultar información de inventario de productos
* URL @param
* @devolver
*/
parseSkuidkey de cadena estática pública (URL de cadena) {
Documento doc=null;
intentar {
doc=abajo(url,"gb2312");
} captura (ClientProtocolException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
} captura (IOException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
//Util.println(doc.select("script"));
Texto de cadena = nulo;
for(Elemento e: doc.select("script")){
if(e.data().contains("skuidkey:")){
texto=e.datos();
romper;
}
}
//skuidkey:'7D45919EA8242511DAA5CC7C6D7B351C'
texto=text.substring(text.indexOf("skuidkey:")+10, text.indexOf("skuidkey:")+42);
Util.println("---------------------------------");
Util.println(texto);
devolver texto;
}
/**
* Ver información de inventario
* @param skuidkey
* @devolver
*/
public static boolean hasStore(String skuidkey){// Este lugar no se procesa, extrae directamente la información en el navegador
Dirección de cadena = nula;
booleano hasStore=false;
si(skuidkey!=null && !"".equals(skuidkey))
dirección="http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
demás{
Util.println("Error al analizar skuidkey");
}
intentar {
if(parseStore(abajo(dirección))){
tieneTienda=verdadero;
}
} captura (ClientProtocolException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
} captura (IOException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
devolver tieneStore;
}
/* if(matriz[1]=="34"||matriz[1]=="18"){
cambiarCarrito(falso);
djdarea.stockInfoDom.html("<strong class='store-over'>Agotado</strong>");
}
de lo contrario si(matriz[1]=="0"){
cambiarCarrito(falso);
djdarea.stockInfoDom.html("<strong class='store-over'>Agotado</strong>");
}
de lo contrario si(matriz[2]=="0"&&matriz[4]!="2"){
cambiarCarrito(falso);
djdarea.stockInfoDom.html("Lo sentimos, este producto no se puede entregar en el área que seleccionó");
}
de lo contrario si(matriz[1]=="33"||matriz[1]=="5"){
cambiarCarrito(verdadero);
djdarea.stockInfoDom.html("<strong>Spot</strong>"+(array[4]=="1"?", el área"+(array[3]=="0"?"No":" ")+"Soporte contra reembolso":"")+cashdesc);
}
de lo contrario si(matriz[1]=="36"){
cambiarCarrito(verdadero);
djdarea.stockInfoDom.html("<strong>Reserva</strong>"+(array[4]=="1"?", el área"+(array[3]=="0"?"No":" ")+"Soporte contra reembolso":"")+cashdesc);
}
de lo contrario si(matriz[1]=="39"){
cambiarCarrito(verdadero);
djdarea.stockInfoDom.html("<strong>En tránsito</strong>"+(array[4]=="1"?", el área"+(array[3]=="0"?"No": " ")+"Soporte contra reembolso":"")+cashdesc);
}
de lo contrario si(matriz[1]=="40"){
cambiarCarrito(verdadero);
djdarea.stockInfoDom.html("<strong>Disponible para distribución</strong>"+(array[4]=="1"?", esta área"+(array[3]=="0"?"No" :"")+"Soporte contra reembolso":"")+cashdesc);
}
*/
/**
* Analizar información de inventario
* @paramdoc
* @devolver
*/
parseStore booleano estático público (documento doc) {
Texto de cadena=doc.text();
String docc=text.substring(text.indexOf("-")-1,text.lastIndexOf(",")-1);
Util.println(docc);
Cadena[] tienda=docc.split("-");
if(tienda[1].equals("34") || tienda[1].equals("18")){
//Agotado
Util.println("Agotado aquí");
devolver falso;
}si no(tienda[1].equals("33") || tienda[1].equals("5")){
//productos al contado
Util.println("En stock aquí");
devolver verdadero;
}
Util.println(tienda[1]);
devolver falso;
}
//Varios métodos de frijol
getPrice público flotante() {
precio de devolución;
}
public void setPrice(precio flotante) {
this.price = precio;
}
getDiscount flotante público() {
descuento de devolución;
}
setDiscount vacío público (descuento flotante) {
this.discount = descuento;
}
}
oenCMD.java
Copie el código de código de la siguiente manera:
vista del paquete.Util;
clase pública oenCMD {
//público estático vacío principal(String[] argumentos) {
//// openWinExe(nulo);
// openExe(null,"http://www.baidu.com");
// }
// Utilice Java para llamar al archivo exe del sistema Windows, como el Bloc de notas, Calc, etc.
público estático vacío openWinExe (comando de cadena, URL de cadena) {
if(comando==nulo ||comando.equals("")){
comando = "cromo "+url;
}
Tiempo de ejecución rn = Runtime.getRuntime();
Proceso p = nulo;
intentar {
p = rn.exec(comando);
} captura (Excepción e) {
System.out.println("¡Error al ganar ejecutivo!");
}
}
// Llame a otros archivos ejecutables, como el exe creado por usted mismo o el software descargado e instalado.
openExe público estático vacío (cadena ruta y nombre, cadena URL) {
if(rutaYNombre==null || rutaYNombre.equals("")){
pathAndName="C://Usuarios//Administrador//AppData//Local//Google//Chrome//Application//chrome.exe";
}
si(url!=null && !url.equals("")){
rutaYNombre+=" ";
rutaYNombre+=url;
}
Tiempo de ejecución rn = Runtime.getRuntime();
Proceso p = nulo;
intentar {
p = rn.exec(rutaYNombre);
} captura (Excepción e) {
System.out.println("¡Error ejecutivo!");
}
}
}