Apresente resumidamente as funções
1. Extraia o link do produto (telefone celular) da página JD Mobile Daily Flash Sale de vez em quando (como 1 minuto).
http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01
2. Envie dados ao backend com base no link do produto extraído para obter preço do produto, descrição, desconto, estoque (se em estoque) e outras informações.
3. Faça julgamentos com base nas informações obtidas.
Se as condições forem atendidas, o navegador será chamado automaticamente (desde que o cromo seja adicionado à variável de ambiente ou o código seja alterado para adicionar o caminho browser.exe ao código e o programa seja modificado) para abrir o pedido do produto página.
4. Na verdade, isso resolve um problema: você não precisa mais atualizar a página da web com frequência ou verificá-la você mesmo;
O login e o envio de pedidos devem ser resolvidos pelo navegador (parece que esses pontos funcionais são mais complicados e não foram processados)
O programa não é perfeito:
Existem vários locais que precisam ser modificados antes da execução:
1. Variáveis de ambiente: o Chrome adiciona variáveis do navegador para facilitar a chamada. . Ou modifique você mesmo o código-fonte e abra-o de outras maneiras.
2. É necessário definir as informações de preço de cada produto da atividade. Isso não é bom, o código fonte deve ser modificado.
A modificação está na função filter().
3. Outro local que precisa ser modificado é
hasStore(String skuidkey)
endereço = "http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
As informações cityid=2800&areaid=...localização deste local. Isso não foi processado. Você precisa descobrir isso sozinho na página do produto do telefone celular.
Na verdade, é relativamente simples. chrome+F12, após modificar a "cidade", região e outras informações, você verá uma solicitação get enviada para segundo plano. Este link contém as informações necessárias. (http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid=64EBD0F20F593D95C72C6EED59B64658&provinceid=1&cityid=2805&areaid=2854) Modifique adequadamente.
Util.java
Copie o código do código da seguinte forma:
visualização do pacote.Util;
importar java.util.ArrayList;
classe pública Util {
public static void print(Objeto o){
System.out.print(o);
}
public static void println(Objeto o){
se(nulo==o)
System.out.println();
outro
System.out.println(o);
}
public static ArrayList<Integer> toArrayList(int[] ints){
if(ints.comprimento==0)
retornar nulo;
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=0;i<ints.length;i++){
al.add(ints[i]);
}
retornar al;
}
}
Miaosha360buy.java
Copie o código do código da seguinte forma:
pacote jingdong;
classe pública Miaosha360buy {
java.util.concurrent.CountDownLatch t= novo java.util.concurrent.CountDownLatch(1);
/**
* @param argumentos
*/
public static void main(String[] args) {
// TODO stub de método gerado automaticamente
System.out.println(Thread.currentThread().getName() + "iniciar");
Miaosha360buy ms360=novo Miaosha360buy();
novo ThreadOne360buy(ms360.t).start();
enquanto(verdadeiro){
tentar {
ms360.t.await();
} catch (InterruptedException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
tentar {
Thread.sleep(1000*60); // Chamado a cada 1 minuto?
} catch (InterruptedException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
ms360.t=new java.util.concurrent.CountDownLatch(1);
novo ThreadOne360buy(ms360.t).start();
System.out.println("Novo passo em enquanto..");
}
}
}
Miaosha360buy.java
Copie o código do código da seguinte forma:
pacote jingdong;
classe pública Miaosha360buy {
java.util.concurrent.CountDownLatch t= novo java.util.concurrent.CountDownLatch(1);
/**
* @param argumentos
*/
public static void main(String[] args) {
// TODO stub de método gerado automaticamente
System.out.println(Thread.currentThread().getName() + "iniciar");
Miaosha360buy ms360=novo Miaosha360buy();
novo ThreadOne360buy(ms360.t).start();
enquanto(verdadeiro){
tentar {
ms360.t.await();
} catch (InterruptedException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
tentar {
Thread.sleep(1000*60); // Chamado a cada 1 minuto?
} catch (InterruptedException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
ms360.t=new java.util.concurrent.CountDownLatch(1);
novo ThreadOne360buy(ms360.t).start();
System.out.println("Novo passo em enquanto..");
}
}
}
ThreadOne360buy.java
Copie o código do código da seguinte forma:
pacote 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 view.Util.Util;
classe pública ThreadOne360buy estende Thread{
java.util.concurrent.CountDownLatch c;
ArrayList al;//Registra a página do produto de venda flash
preço flutuante = 0,0f; // preço do produto
float desconto=0.0f;//desconto do produto
//Usado para salvar informações do thread, não é muito útil neste projeto
private static List<Thread> runningThreads = new ArrayList<Thread>();
//Este é um contador (não é muito bom em usá-lo, threads sempre pareceram mais complicados)
public ThreadOne360buy(java.util.concurrent.CountDownLatch c) {
isto.c=c;
}
@Substituir
execução void pública() {
registrar(this); //Registra quando a thread inicia
//imprime a tag inicial
System.out.println(Thread.currentThread().getName() + "Iniciar...");
tentar {
//Veja a página de venda relâmpago do celular Jingdong
this.getMessage("http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01");
} catch (ClientProtocolException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
c.contagemDown();
} catch (IOException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
c.contagemDown();
}
c.contagemDown();
unRegist(this); //Cancela o registro quando o thread termina
//imprime a tag final
System.out.println(Thread.currentThread().getName() + "End.");
}
registro público void(Thread t) {
sincronizado (runningThreads) {
executandoThreads.add(t);
}
}
public void unRegist(Thread t) {
sincronizado (runningThreads) {
runningThreads.remove(t);
}
}
public static boolean hasThreadRunning() {
// Ao avaliar se runningThreads está vazio, você pode saber se há algum thread que ainda não foi executado.
return (runningThreads.size() > 0);
}
/**
* Obtenha o link do produto, skuid do produto, skuidkey, preço e informações da loja na página de venda flash móvel
* @param url: página de venda flash para celular
* @throws ClientProtocolException
* @throwsIOException
*/
public void getMessage(String url) lança ClientProtocolException, IOException{
al=getMainUrl(down(url));
Util.println(al);
if(al.size()==0){
c.contagemDown();
Sistema.exit(0);
retornar;
}
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());
//O que fica salvo no mapa são o nome do produto, preço e informações de desconto.
Util.println("Al("+i+") down:"+sb.toString());
HashMap<String, String> hm=parseProduct(down(sb.toString()));
//Usado para combinar informações de preço. Corresponder informações de inventário
filter(hm,openUrl.toString());//Filtre o preço e abra o navegador se as condições forem atendidas
}
}
/**
* Um método de verificação
* @param hm contém informações de preços
* @param URL da página do produto
*/
public void filter(HashMap<String, String> hm,String url){//url é a página do produto
//view.Util.oenCMD.openWinExe(null,url);
//Devemos verificar o inventário primeiro?
String skuidkey=parseSkuidkey(url);
if(!hasStore(skuidkey)){
Util.println("-------------------------------------------");
Util.println("Esgotado!");
Util.println("-------------------------------------------");
//Diminui a contagem para que o thread principal possa julgar
c.contagemDown();
//Devemos encerrar o thread filho?
retornar;
}
if(hm.get("skuid").equals("201602")){//Julgamento//Motorola skuid=201602
//O preço aqui é codificado e precisa ser alterado antes da execução.
this.setPrice(499.0f);
//O console deve ser aberto?
if(Float.parseFloat(hm.get("preço"))<=this.getPrice()){
visualizar.Util.oenCMD.openWinExe(null,url);
}
}else if(hm.get("skuid").equals("675647")){//Tianyu skuid=675647
////O preço aqui é codificado e precisa ser alterado antes da execução.
//this.setPrice(699.0f);
////O console deve ser aberto?
//if(Float.parseFloat(hm.get("preço"))<=this.getPrice()){
//view.Util.oenCMD.openWinExe(null,url);
//}
}
}
/**
* Analisou o nome, skuid e informações de preço na página do produto
* @paramdoc
* @retornar
*/
public static HashMap<String, String> parseProduct(Documento doc){
String texto=doc.text();
String docc=text.substring(text.indexOf("master")+9,text.indexOf("acessórios")-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);
retorne hm;
}
/**
* Processe caracteres Unicode e converta-os em caracteres de exibição (caracteres chineses), o que não é muito versátil.
* @param it: /u6a5d
* @retornar
*/
public static String unicodeDecode(String it){//Uma desvantagem é que os caracteres anteriores não podem ser removidos
Util.println(it);
String regex="(////u[0-9a-f]{4})";
Padrão pt= Padrão.compile(regex);
Combinador mc;
StringBuffer sb;
StringBuffer sba=new StringBuffer();
mc=pt.matcher(it);
enquanto(mc.find()){
sb=new StringBuffer();
mc.appendReplacement(sba,sb.append((char )Integer.parseInt((mc.group(1).substring(2)), 16)).toString());
}
retornar sba.toString();
}
/**
* Retornar objeto de documento (baixar conteúdo)
* Página de download do URL @param
* @retornar
* @throws ClientProtocolException
* @throwsIOException
*/
Public static Document down (String url) lança ClientProtocolException, IOException{
Documento doc = null;
DefaultHttpClient httpClient=new DefaultHttpClient();
Util.println("DownLoad:"+url);
HttpGet get=new HttpGet(url);
Resposta HttpResponse;
resposta = httpClient.execute(get);
Entidade HttpEntity = resposta.getEntity();
doc = Jsoup.parse(entity.getContent(), "utf-8","");
// Libera recursos
EntityUtils.consume(entidade);
//Fecha a conexão
httpClient.getConnectionManager().shutdown();
documento de retorno;
}
/**
* Adicionadas informações de controle de codificação
* @param url da página a ser baixada
* Codificação de código @param
* @retornar
* @throws ClientProtocolException
* @throwsIOException
*/
Public static Document down (String url, String code) lança ClientProtocolException, IOException{
Documento doc = null;
DefaultHttpClient httpClient=new DefaultHttpClient();
Util.println("DownLoad:"+url);
HttpGet get=new HttpGet(url);
Resposta HttpResponse;
resposta = httpClient.execute(get);
Entidade HttpEntity = resposta.getEntity();
doc = Jsoup.parse(entity.getContent(), código,"");
// Libera recursos
EntityUtils.consume(entidade);
//Fecha a conexão
httpClient.getConnectionManager().shutdown();
documento de retorno;
}
/**
* Usado para analisar links de produtos (coleções) em páginas de venda relâmpago
* @paramdoc
* @retornar
*/
public static ArrayList<String> getMainUrl(Documento doc){
if(doc.equals("")||doc==null)
retornar nulo;
tentar {
Thread.sleep(50);
} catch (InterruptedException e1) {
// TODO Bloco catch gerado automaticamente
e1.printStackTrace();
}
ArrayList<String> urls=new ArrayList<String>();
String regra="mapa[nome=Mapa] >area[href~=produto]";
/**
* Comece a analisar
*/
Elementos elementos=doc.select(rule);
for (Elemento e: elementos) {
//Util.println(e.absUrl("abs:href"));
urls.add(e.absUrl("abs:href"));
}
URLs de retorno;
}
/**
* Obtenha o skuidkey para consultar informações de inventário de produtos
*@paramurl
* @retornar
*/
string estática pública parseSkuidkey(String url){
Documento doc=nulo;
tentar {
doc=down(url,"gb2312");
} catch (ClientProtocolException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
} catch (IOException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
//Util.println(doc.select("script"));
String texto = nulo;
for(Elemento e: doc.select("script")){
if(e.data().contains("skuidkey:")){
texto=e.dados();
quebrar;
}
}
//skuidkey:'7D45919EA8242511DAA5CC7C6D7B351C'
text=text.substring(text.indexOf("skuidkey:")+10, text.indexOf("skuidkey:")+42);
Util.println("---------------------------------");
Util.println(texto);
retornar texto;
}
/**
* Ver informações de inventário
* @param skuidkey
* @retornar
*/
public static boolean hasStore(String skuidkey){//Este local não é processado, extraia diretamente as informações no navegador
Endereço de string = nulo;
booleano hasStore=falso;
if(skuidkey!=null && !"".equals(skuidkey))
endereço = "http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
outro{
Util.println("Erro ao analisar o skuidkey");
}
tentar {
if(parseStore(down(endereço))){
hasStore=true;
}
} catch (ClientProtocolException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
} catch (IOException e) {
// TODO Bloco catch gerado automaticamente
e.printStackTrace();
}
retornar hasStore;
}
/* if(array[1]=="34"||array[1]=="18"){
alterarCarrinho(falso);
djdarea.stockInfoDom.html("<strong class='store-over'>Esgotado</strong>");
}
senão if(array[1]=="0"){
alterarCarrinho(falso);
djdarea.stockInfoDom.html("<strong class='store-over'>Esgotado</strong>");
}
senão if(array[2]=="0"&&array[4]!="2"){
alterarCarrinho(falso);
djdarea.stockInfoDom.html("Desculpe, este produto não pode ser entregue na área que você selecionou");
}
senão if(array[1]=="33"||array[1]=="5"){
alterarCarrinho(verdadeiro);
djdarea.stockInfoDom.html("<strong>Spot</strong>"+(array[4]=="1"?", a área"+(array[3]=="0"?"Não":" ")+"Apoio em dinheiro na entrega":"")+cashdesc);
}
senão if(array[1]=="36"){
alterarCarrinho(verdadeiro);
djdarea.stockInfoDom.html("<strong>Reserva</strong>"+(array[4]=="1"?", a área"+(array[3]=="0"?"Não":" ")+"Apoio em dinheiro na entrega":"")+cashdesc);
}
senão if(array[1]=="39"){
alterarCarrinho(verdadeiro);
djdarea.stockInfoDom.html("<strong>Em trânsito</strong>"+(array[4]=="1"?", a área"+(array[3]=="0"?"Não": " ")+"Apoio em dinheiro na entrega":"")+cashdesc);
}
senão if(array[1]=="40"){
alterarCarrinho(verdadeiro);
djdarea.stockInfoDom.html("<strong>Disponível para distribuição</strong>"+(array[4]=="1"?", esta área"+(array[3]=="0"?"Não" :"")+"Apoio em dinheiro na entrega":"")+cashdesc);
}
*/
/**
* Analisar informações de inventário
* @paramdoc
* @retornar
*/
public static boolean parseStore(documento){
String text=doc.text();
String docc=text.substring(text.indexOf("-")-1,text.lastIndexOf(",")-1);
Util.println(docc);
String[] store=docc.split("-");
if(loja[1].equals("34") || loja[1].equals("18")){
//fora de estoque
Util.println("Esgotado aqui");
retornar falso;
}else if(store[1].equals("33") || store[1].equals("5")){
//Produtos localizados
Util.println("Em estoque aqui");
retornar verdadeiro;
}
Util.println(loja[1]);
retornar falso;
}
//Vários métodos de bean
public float getPreço() {
preço de retorno;
}
public void setPrice(preço flutuante) {
este.preço = preço;
}
public float getDesconto() {
desconto de devolução;
}
public void setDiscount(desconto flutuante) {
this.discount = desconto;
}
}
oenCMD.java
Copie o código do código da seguinte forma:
visualização do pacote.Util;
classe pública oenCMD {
//public static void main(String[] args) {
//// openWinExe(null);
// openExe(null,"http://www.baidu.com");
// }
//Use Java para chamar o arquivo exe do sistema Windows, como bloco de notas, calc, etc.
public static void openWinExe(String comando,String url) {
if(command==null ||command.equals("")){
comando = "cromo "+url;
}
Tempo de execução rn = Runtime.getRuntime();
Processo p = nulo;
tentar {
p = rn.exec(comando);
} catch (Exceção e) {
System.out.println("Erro ao executar exec!");
}
}
//Chama outros arquivos executáveis, como exe feitos por você mesmo ou software baixado e instalado.
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("")){
caminhoAndNome+=" ";
caminhoAndNome+=url;
}
Tempo de execução rn = Runtime.getRuntime();
Processo p = nulo;
tentar {
p = rn.exec(caminhoAndNome);
} catch (Exceção e) {
System.out.println("Erro exec!");
}
}
}