Présenter brièvement les fonctions
1. Extrayez le lien du produit (téléphone mobile) de la page de vente flash quotidienne de JD Mobile de temps en temps (par exemple 1 minute).
http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01
2. Envoyez des données au backend en fonction du lien produit extrait pour obtenir le prix du produit, la description, la remise, l'inventaire (si en stock) et d'autres informations.
3. Portez des jugements sur la base des informations obtenues.
Si les conditions sont remplies, le navigateur sera automatiquement appelé (à condition que chrome soit ajouté à la variable d'environnement, ou que le code soit modifié pour ajouter le chemin browser.exe au code, et que le programme soit modifié) pour ouvrir la commande du produit page.
4. En fait, cela résout un problème : vous n'avez plus besoin d'actualiser fréquemment la page Web ou de la vérifier vous-même ;
La connexion et la soumission des commandes doivent être résolues par le navigateur (il semble que ces points fonctionnels soient plus compliqués et n'aient pas été traités)
Le programme n'est pas parfait :
Il y a plusieurs endroits qui doivent être modifiés avant de fonctionner :
1. Variables d'environnement : Chrome ajoute des variables de navigateur pour faciliter les appels. . Ou modifiez vous-même le code source et ouvrez-le d'une autre manière.
2. Les informations sur les prix de chaque produit de l'activité doivent être définies. Ce n'est pas bon, le code source doit être modifié.
La modification est dans la fonction filter().
3. Un autre endroit qui doit être modifié est
hasStore (Skuidkey de chaîne)
adresse="http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
Les informations de localisation cityid=2800&areaid=... de ce lieu. Cela n'a pas été traité. Vous devez le découvrir vous-même à partir de la page produit du téléphone mobile.
C'est en fait relativement simple. chrome+F12, après avoir modifié la "ville", la région et d'autres informations, vous verrez une requête get envoyée en arrière-plan. Ce lien contient les informations requises. (http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid=64EBD0F20F593D95C72C6EED59B64658&provinceid=1&cityid=2805&areaid=2854) Modifiez en conséquence.
Util.java
Copiez le code comme suit :
vue du paquet.Util;
importer java.util.ArrayList ;
classe publique Util {
public static void print(Objet o){
System.out.print(o);
}
public static void println(Objet o){
si(null==o)
System.out.println();
autre
System.out.println(o);
}
public static ArrayList<Integer> toArrayList(int[] ints){
si(ints.length==0)
renvoie null ;
ArrayList<Integer> al=new ArrayList<Integer>();
pour(int i=0;i<ints.length;i++){
al.add(ints[i]);
}
retourner al;
}
}
Miaosha360buy.java
Copiez le code comme suit :
paquet Jingdong;
classe publique Miaosha360buy {
java.util.concurrent.CountDownLatch t= new java.util.concurrent.CountDownLatch(1);
/**
* @param arguments
*/
public static void main (String[] arguments) {
// TODO Stub de méthode généré automatiquement
System.out.println(Thread.currentThread().getName() + "start");
Miaosha360buy ms360=nouveau Miaosha360buy();
nouveau ThreadOne360buy(ms360.t).start();
tandis que(vrai){
essayer {
ms360.t.attendre();
} catch (InterruptedException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
essayer {
Thread.sleep(1000*60); // Appelé toutes les minutes ?
} catch (InterruptedException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
ms360.t=nouveau java.util.concurrent.CountDownLatch(1);
nouveau ThreadOne360buy(ms360.t).start();
System.out.println("Nouvelle bande de roulement dans while..");
}
}
}
Miaosha360buy.java
Copiez le code comme suit :
paquet Jingdong;
classe publique Miaosha360buy {
java.util.concurrent.CountDownLatch t= new java.util.concurrent.CountDownLatch(1);
/**
* @param arguments
*/
public static void main (String[] arguments) {
// TODO Stub de méthode généré automatiquement
System.out.println(Thread.currentThread().getName() + "start");
Miaosha360buy ms360=nouveau Miaosha360buy();
nouveau ThreadOne360buy(ms360.t).start();
tandis que(vrai){
essayer {
ms360.t.attendre();
} catch (InterruptedException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
essayer {
Thread.sleep(1000*60); // Appelé toutes les minutes ?
} catch (InterruptedException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
ms360.t=nouveau java.util.concurrent.CountDownLatch(1);
nouveau ThreadOne360buy(ms360.t).start();
System.out.println("Nouvelle bande de roulement dans while..");
}
}
}
ThreadOne360buy.java
Copiez le code comme suit :
paquet Jingdong;
importer java.io.IOException ;
importer java.util.ArrayList ;
importer java.util.HashMap ;
importer java.util.List ;
importer java.util.regex.Matcher ;
importer java.util.regex.Pattern ;
importer org.apache.http.HttpEntity ;
importer org.apache.http.HttpResponse ;
importer org.apache.http.client.ClientProtocolException ;
importer org.apache.http.client.methods.HttpGet ;
importer org.apache.http.impl.client.DefaultHttpClient ;
importer org.apache.http.util.EntityUtils ;
importer org.jsoup.Jsoup ;
importer org.jsoup.nodes.Document ;
importer org.jsoup.nodes.Element ;
importer org.jsoup.select.Elements ;
importer view.Util.Util ;
la classe publique ThreadOne360buy étend Thread{
java.util.concurrent.CountDownLatch c;
ArrayList al;//Page produit de la vente flash d'enregistrement
prix flottant = 0,0f ; // prix du produit
remise flottante = 0,0f ; // Remise sur le produit
//Utilisé pour sauvegarder les informations du thread, pas très utile dans ce projet
private static List<Thread> runningThreads = new ArrayList<Thread>();
// Ceci est un compteur (pas très doué pour l'utiliser, les discussions ont toujours semblé plus compliquées)
public ThreadOne360buy(java.util.concurrent.CountDownLatch c) {
ceci.c=c;
}
@Outrepasser
public void run() {
register(this);//S'inscrire au démarrage du fil de discussion
// affiche la balise de début
System.out.println(Thread.currentThread().getName() + "Démarrer...");
essayer {
// Consultez la page de vente flash des téléphones mobiles de Jingdong
this.getMessage("http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01");
} catch (ClientProtocolException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
c.countDown();
} catch (IOException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
c.countDown();
}
c.countDown();
unRegist(this);//Se désinscrire à la fin du fil de discussion
// imprimer la balise de fin
System.out.println(Thread.currentThread().getName() + "End.");
}
registre vide public (thread t) {
synchronisé (runningThreads) {
runningThreads.add(t);
}
}
public void unRegist (Thread t) {
synchronisé (runningThreads) {
runningThreads.remove(t);
}
}
public statique booléen hasThreadRunning() {
// En jugeant si runningThreads est vide, vous pouvez savoir s'il y a des threads qui n'ont pas encore été exécutés.
return (runningThreads.size() > 0);
}
/**
* Obtenez le lien du produit, le skuid du produit, le skuidkey, le prix et les informations sur le magasin à partir de la page de vente flash mobile
* @param url : page de vente flash mobile
* @throws ClientProtocolException
* @throwsIOException
*/
public void getMessage (String url) lance ClientProtocolException, IOException {
al=getMainUrl(down(url));
Util.println(al);
si(al.size()==0){
c.countDown();
Système.exit(0);
retour;
}
pour(int i=0;i<al.size();i++){
StringBuffer sb=nouveau 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());
//Ce qui est enregistré dans la carte, ce sont le nom du produit, son prix et les informations sur la remise.
Util.println("Al("+i+") down:"+sb.toString());
HashMap<String, String> hm=parseProduct(down(sb.toString()));
//Utilisé pour faire correspondre les informations sur les prix. Faire correspondre les informations d'inventaire
filter(hm,openUrl.toString());//Filtrer le prix et ouvrir le navigateur si les conditions sont remplies
}
}
/**
* Une méthode de vérification
* @param hm détient des informations sur les prix
* Page produit URL @param
*/
public void filter(HashMap<String, String> hm,String url){//url est la page produit
//view.Util.oenCMD.openWinExe(null,url);
//Devrions-nous d'abord vérifier l'inventaire ?
Chaîne skuidkey=parseSkuidkey(url);
if(!hasStore(skuidkey)){
Util.println("----------------------------------------");
Util.println("En rupture de stock !");
Util.println("----------------------------------------");
// Diminuez le nombre pour que le thread principal puisse juger
c.countDown();
//Devrions-nous mettre fin au fil de discussion enfant ?
retour;
}
if(hm.get("skuid").equals("201602")){//Judgement//Motorola skuid=201602
//Le prix ici est codé en dur et doit être modifié avant d'être exécuté.
this.setPrice(499.0f);
// Faut-il ouvrir la console ?
if(Float.parseFloat(hm.get("price"))<=this.getPrice()){
view.Util.oenCMD.openWinExe(null,url);
}
}else if(hm.get("skuid").equals("675647")){//Tianyu skuid=675647
////Le prix ici est codé en dur et doit être modifié avant d'être exécuté.
//this.setPrice(699.0f);
////Faut-il ouvrir la console ?
//if(Float.parseFloat(hm.get("price"))<=this.getPrice()){
//view.Util.oenCMD.openWinExe(null,url);
//}
}
}
/**
* Analyse du nom, du skuid et des informations sur le prix dans la page produit
* @paramdoc
* @retour
*/
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>();
pour(Chaîne-le : ss){
String string=it.replaceAll("/"", "");
si(string.contains("//u"))
string=unicodeDecode(string);
String[] str=string.split(":");
hm.put(str[0], str[1]);
}
Util.println(hm);
reviens hum;
}
/**
* Traitez les caractères Unicode et convertissez-les en caractères d'affichage (caractères chinois), ce qui n'est pas très polyvalent.
* @param : /u6a5d
* @retour
*/
public static String unicodeDecode(String it){//Un inconvénient est que les caractères précédents ne peuvent pas être supprimés
Util.println(it);
Chaîne regex="(////u[0-9a-f]{4})";
Modèle pt= Pattern.compile(regex);
Matcher mc;
StringBuffer qn;
StringBuffer sba=nouveau StringBuffer();
mc=pt.matcher(it);
tandis que(mc.find()){
sb=nouveau StringBuffer();
mc.appendReplacement(sba,sb.append((char )Integer.parseInt((mc.group(1).substring(2)), 16)).toString());
}
return sba.toString();
}
/**
* Renvoyer l'objet du document (télécharger le contenu)
* Page de téléchargement de l'URL @param
* @retour
* @throws ClientProtocolException
* @throwsIOException
*/
Le document statique public down (URL de chaîne) lève ClientProtocolException, IOException {
Document doc = nul ;
DefaultHttpClient httpClient=new DefaultHttpClient();
Util.println("DownLoad:"+url);
HttpGet get=nouveau HttpGet(url);
Réponse HttpResponse ;
réponse = httpClient.execute(get);
Entité HttpEntity = réponse.getEntity();
doc = Jsoup.parse(entity.getContent(), "utf-8","");
// Libérer des ressources
EntityUtils.consume(entité);
//Ferme la connexion
httpClient.getConnectionManager().shutdown();
retourner le document ;
}
/**
* Ajout d'informations de contrôle d'encodage
* Page url @param à télécharger
* Encodage du code @param
* @retour
* @throws ClientProtocolException
* @throwsIOException
*/
Le document statique public down (URL de chaîne, code de chaîne) renvoie ClientProtocolException, IOException {
Document doc = nul ;
DefaultHttpClient httpClient=new DefaultHttpClient();
Util.println("DownLoad:"+url);
HttpGet get=nouveau HttpGet(url);
Réponse HttpResponse ;
réponse = httpClient.execute(get);
Entité HttpEntity = réponse.getEntity();
doc = Jsoup.parse(entity.getContent(), code,"");
// Libérer des ressources
EntityUtils.consume(entité);
//Ferme la connexion
httpClient.getConnectionManager().shutdown();
retourner le document ;
}
/**
* Utilisé pour analyser les liens de produits (collections) dans les pages de vente flash
* @paramdoc
* @retour
*/
public static ArrayList<String> getMainUrl(Document doc){
if(doc.equals("")||doc==null)
renvoie null ;
essayer {
Thread.sleep(50);
} catch (InterruptedException e1) {
// TODO Bloc catch généré automatiquement
e1.printStackTrace();
}
ArrayList<String> urls=new ArrayList<String>();
String Rule="map[name=Map] >area[href~=product]";
/**
* Commencez l'analyse
*/
Elements elements=doc.select(règle);
pour (Élément e : éléments) {
//Util.println(e.absUrl("abs:href"));
urls.add(e.absUrl("abs:href"));
}
renvoyer les URL ;
}
/**
* Obtenez skuidkey pour interroger les informations sur l'inventaire des produits
* URL @param
* @retour
*/
chaîne statique publique parseSkuidkey (URL de chaîne) {
Document doc=null ;
essayer {
doc=down(url,"gb2312");
} catch (ClientProtocolException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (IOException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
//Util.println(doc.select("script"));
Texte de chaîne = nul ;
pour(Élément e : doc.select("script")){
if(e.data().contains("skuidkey:")){
text=e.data();
casser;
}
}
//Skuidkey:'7D45919EA8242511DAA5CC7C6D7B351C'
text=text.substring(text.indexOf("skuidkey:")+10, text.indexOf("skuidkey:")+42);
Util.println("---------------------------------");
Util.println(texte);
renvoyer du texte ;
}
/**
* Afficher les informations d'inventaire
* @param skuidkey
* @retour
*/
public static boolean hasStore(String skuidkey){//Cet endroit n'est pas traité, extrayez directement les informations dans le navigateur
Adresse de chaîne = null ;
booléen hasStore=false ;
if(skuidkey!=null && !"".equals(skuidkey))
adresse="http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
autre{
Util.println("Erreur lors de l'analyse de skuidkey");
}
essayer {
if(parseStore(down(adresse))){
hasStore=true;
}
} catch (ClientProtocolException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} catch (IOException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
}
retourner hasStore ;
}
/* si(array[1]=="34"||array[1]=="18"){
changeCart(faux);
djdarea.stockInfoDom.html("<strong class='store-over'>En rupture de stock</strong>");
}
sinon if(array[1]=="0"){
changeCart(faux);
djdarea.stockInfoDom.html("<strong class='store-over'>En rupture de stock</strong>");
}
sinon if(array[2]=="0"&&array[4]!="2"){
changeCart(faux);
djdarea.stockInfoDom.html("Désolé, ce produit ne peut pas être livré dans la zone que vous avez sélectionnée");
}
sinon if(array[1]=="33"||array[1]=="5"){
changeCart(true);
djdarea.stockInfoDom.html("<strong>Spot</strong>"+(array[4]=="1"?", la zone"+(array[3]=="0"?"No":" ")+"Support paiement à la livraison":"")+cashdesc);
}
sinon si(array[1]=="36"){
changeCart(true);
djdarea.stockInfoDom.html("<strong>Réservation</strong>"+(array[4]=="1"?", la zone"+(array[3]=="0"?"No":" ")+"Support paiement à la livraison":"")+cashdesc);
}
sinon si(array[1]=="39"){
changeCart(true);
djdarea.stockInfoDom.html("<strong>En transit</strong>"+(array[4]=="1"?", la zone"+(array[3]=="0"?"No": " ")+"Prise en charge du paiement à la livraison": "")+cashdesc);
}
sinon si(array[1]=="40"){
changeCart(true);
djdarea.stockInfoDom.html("<strong>Disponible pour distribution</strong>"+(array[4]=="1"?", cette zone"+(array[3]=="0"?"Non" :"")+"Support paiement à la livraison":"")+cashdesc);
}
*/
/**
* Analyser les informations d'inventaire
* @paramdoc
* @retour
*/
parseStore booléen statique public (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")){
//en rupture de stock
Util.println("En rupture de stock ici");
renvoie faux ;
}else if(store[1].equals("33") || store[1].equals("5")){
//Marchandises ponctuelles
Util.println("En stock ici");
renvoie vrai ;
}
Util.println(magasin[1]);
renvoie faux ;
}
//Plusieurs méthodes du bean
public float getPrice() {
prix de retour ;
}
public void setPrice (prix flottant) {
this.price = prix ;
}
public float getDiscount() {
remise de retour ;
}
public void setDiscount (remise flottante) {
this.discount = remise ;
}
}
oenCMD.java
Copiez le code comme suit :
vue du paquet.Util;
classe publique oenCMD {
//public static void main(String[] args) {
//// openWinExe(null);
// openExe(null,"http://www.baidu.com");
// }
//Utilisez Java pour appeler le fichier exe du système Windows, tel que le bloc-notes, calc, etc.
public static void openWinExe (commande String, URL String) {
if(command==null ||command.equals("")){
commande = "chrome "+url ;
}
Runtime rn = Runtime.getRuntime();
Processus p = nul ;
essayer {
p = rn.exec(commande);
} attraper (Exception e) {
System.out.println("Erreur lors de la victoire d'exécution !");
}
}
//Appelle d'autres fichiers exécutables, tels qu'un exe créé par vous-même ou un logiciel téléchargé et installé.
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("")){
cheminEtNom+=" ";
cheminEtNom+=url;
}
Exécution rn = Runtime.getRuntime();
Processus p = nul ;
essayer {
p = rn.exec(cheminEtNom);
} attraper (Exception e) {
System.out.println("Erreur d'exécution !");
}
}
}