أعرض بإيجاز الوظائف
1. قم باستخراج رابط المنتج (الهاتف المحمول) من صفحة JD Mobile Daily Flash Sale من حين لآخر (مثل دقيقة واحدة).
http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01
2. إرسال البيانات إلى الواجهة الخلفية بناءً على رابط المنتج المستخرج للحصول على سعر المنتج والوصف والخصم والمخزون (سواء كان موجودًا في المخزون) وغيرها من المعلومات.
3. إصدار الأحكام بناءً على المعلومات التي تم الحصول عليها.
في حالة استيفاء الشروط سيتم استدعاء المتصفح تلقائيا (بشرط إضافة الكروم إلى متغير البيئة أو تغيير الكود لإضافة مسار browser.exe إلى الكود وتعديل البرنامج) لفتح طلب المنتج صفحة.
4. في الواقع، هذا يحل مشكلة: لم تعد بحاجة إلى تحديث صفحة الويب بشكل متكرر أو التحقق منها بنفسك؛
يجب أن يتم حل مشكلة تسجيل الدخول وتقديم الطلبات عن طريق المتصفح (يبدو أن هذه النقاط الوظيفية أكثر تعقيدًا ولم تتم معالجتها)
البرنامج ليس مثاليا:
هناك عدة أماكن تحتاج إلى تعديل قبل التشغيل:
1. متغيرات البيئة: يضيف Chrome متغيرات المتصفح لتسهيل الاتصال. . أو قم بتعديل كود المصدر بنفسك وافتحه بطرق أخرى.
2. يجب تحديد معلومات سعر كل منتج في النشاط. هذا ليس جيدًا، يجب تعديل كود المصدر.
التعديل موجود في وظيفة التصفية ().
3. المكان الآخر الذي يحتاج إلى تعديل هو
hasStore (سلسلة skuidkey)
عنوان = "http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
the cityid=2800&areaid=...معلومات الموقع لهذا المكان. لم تتم معالجة هذا. تحتاج إلى معرفة ذلك بنفسك من صفحة منتج الهاتف المحمول.
إنها في الواقع بسيطة نسبيًا. chrome+F12، بعد تعديل "المدينة" والمنطقة والمعلومات الأخرى، سترى طلب الحصول مرسلاً إلى الخلفية. يحتوي هذا الرابط على المعلومات المطلوبة. (http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid=64EBD0F20F593D95C72C6EED59B64658&provinceid=1&cityid=2805&areaid=2854) قم بالتعديل بشكل مناسب.
Util.java
انسخ رمز الكود كما يلي:
view.Util;
import java.util.ArrayList;
الطبقة العامة Util {
طباعة باطلة ثابتة عامة (كائن س) {
System.out.print(o);
}
طباعة باطلة عامة ثابتة (كائن س) {
إذا (خالية == س)
System.out.println();
آخر
System.out.println(o);
}
ArrayList العام الثابت<Integer> toArrayList(int[] ints){
إذا (ints.length==0)
عودة فارغة؛
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=0;i<ints.length;i++){
al.add(ints[i]);
}
عودة آل؛
}
}
Miaosha360buy.java
انسخ رمز الكود كما يلي:
حزمة جينغدونغ.
الطبقة العامة Miaosha360buy {
java.util.concurrent.CountDownLatch t= new java.util.concurrent.CountDownLatch(1);
/**
* @param args
*/
public static void main(String[] args) {
// TODO طريقة تم إنشاؤها تلقائيًا stub
System.out.println(Thread.currentThread().getName() + "start");
Miaosha360buy ms360=new Miaosha360buy();
new ThreadOne360buy(ms360.t).start();
بينما (صحيح) {
يحاول {
ms360.t.await();
} قبض على (InterruptedException e) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
يحاول {
Thread.sleep(1000*60);// هل يتم الاتصال به كل دقيقة؟
} قبض على (InterruptedException e) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
ms360.t=new java.util.concurrent.CountDownLatch(1);
new ThreadOne360buy(ms360.t).start();
System.out.println("مداس جديد أثناء ..");
}
}
}
Miaosha360buy.java
انسخ رمز الكود كما يلي:
حزمة جينغدونغ.
الطبقة العامة Miaosha360buy {
java.util.concurrent.CountDownLatch t= new java.util.concurrent.CountDownLatch(1);
/**
* @param args
*/
public static void main(String[] args) {
// TODO طريقة تم إنشاؤها تلقائيًا stub
System.out.println(Thread.currentThread().getName() + "start");
Miaosha360buy ms360=new Miaosha360buy();
new ThreadOne360buy(ms360.t).start();
بينما (صحيح) {
يحاول {
ms360.t.await();
} قبض على (InterruptedException e) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
يحاول {
Thread.sleep(1000*60);// هل يتم الاتصال به كل دقيقة؟
} قبض على (InterruptedException e) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
ms360.t=new java.util.concurrent.CountDownLatch(1);
new ThreadOne360buy(ms360.t).start();
System.out.println("مداس جديد أثناء ..");
}
}
}
ThreadOne360buy.java
انسخ رمز الكود كما يلي:
حزمة جينغدونغ.
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;
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;
الطبقة العامة ThreadOne360buy تمتد الموضوع {
java.util.concurrent.CountDownLatch c;
ArrayList al;//سجل صفحة منتج بيع فلاش
السعر العائم = 0.0f;//سعر المنتج
خصم التعويم = 0.0f;//خصم المنتج
// يُستخدم لحفظ معلومات الموضوع، وهو ليس مفيدًا جدًا في هذا المشروع
قائمة ثابتة خاصة <Thread> RunningThreads = new ArrayList<Thread>();
// هذا عداد (ليس جيدًا في استخدامه، حيث كانت الخيوط تبدو دائمًا أكثر تعقيدًا)
public ThreadOne360buy(java.util.concurrent.CountDownLatch c) {
this.c=c;
}
@تجاوز
تشغيل الفراغ العام () {
تسجيل (هذا)؛ // سجل عند بدء الموضوع
// طباعة علامة البداية
System.out.println(Thread.currentThread().getName() + "ابدأ...");
يحاول {
// احصل على صفحة بيع فلاش الهاتف المحمول Jingdong
this.getMessage("http://sale.360buy.com/act/8VTHFGr10CjMDyZ.html#01");
} قبض على (ClientProtocolException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
c.countDown();
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
c.countDown();
}
c.countDown();
unRegist(this);// إلغاء التسجيل عند انتهاء الموضوع
// طباعة علامة النهاية
System.out.println(Thread.currentThread().getName() + "End.");
}
تسجيل الفراغ العام (الموضوع t) {
متزامن (تشغيل المواضيع) {
RunningThreads.add(t);
}
}
الفراغ العام unRegist (الموضوع t) {
متزامن (تشغيل المواضيع) {
runThreads.remove(t);
}
}
منطقية عامة ثابتة hasThreadRunning() {
// من خلال الحكم على ما إذا كان RunningThreads فارغًا، يمكنك معرفة ما إذا كان هناك أي سلاسل رسائل لم يتم تنفيذها بعد.
العودة (runningThreads.size() > 0);
}
/**
* احصل على رابط المنتج وSkuid المنتج وSkuidkey والسعر ومعلومات المتجر من صفحة بيع فلاش الهاتف المحمول
* @param url: صفحة بيع فلاش المحمول
* @throws ClientProtocolException
* @throwsIOException
*/
getMessage الفراغ العام (String url) يطرح ClientProtocolException، IOException {
al=getMainUrl(down(url));
Util.println(al);
إذا(al.size()==0){
c.countDown();
System.exit(0);
يعود؛
}
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());
// ما يتم حفظه في الخريطة هو اسم المنتج وسعره ومعلومات الخصم.
Util.println("Al("+i+") down:"+sb.toString());
HashMap<String, String> hm=parseProduct(down(sb.toString()));
// يستخدم لمطابقة معلومات السعر. مطابقة معلومات المخزون
filter(hm,openUrl.toString());// قم بتصفية السعر وافتح المتصفح في حالة استيفاء الشروط
}
}
/**
* طريقة التحقق
* @param hm يحمل معلومات السعر
* @param صفحة المنتج url
*/
مرشح الفراغ العام (HashMap<String, String> hm,String url) {// url هو صفحة المنتج
//view.Util.oenCMD.openWinExe(null,url);
// هل يجب أن نتحقق من المخزون أولاً؟
String skuidkey=parseSkuidkey(url);
إذا(!hasStore(skuidkey)){
Util.println("----------------------------------------");
Util.println("نفاد المخزون!");
Util.println("----------------------------------------");
// قلل العدد حتى يتمكن الخيط الرئيسي من الحكم
c.countDown();
// هل يجب أن ننهي الخيط الفرعي؟
يعود؛
}
if(hm.get("skuid").equals("201602")){//الحكم//Motorola skuid=201602
// السعر هنا مشفر ويجب تغييره قبل التشغيل.
this.setPrice(499.0f);
// هل يجب فتح وحدة التحكم؟
إذا(Float.parseFloat(hm.get("price"))<=this.getPrice()){
view.Util.oenCMD.openWinExe(null,url);
}
}else if(hm.get("skuid").equals("675647")){// Tianyu skuid=675647
//// السعر هنا مشفر ويجب تغييره قبل التشغيل.
//this.setPrice(699.0f);
//// هل يجب فتح وحدة التحكم؟
//if(Float.parseFloat(hm.get("price"))<=this.getPrice()){
//view.Util.oenCMD.openWinExe(null,url);
//
}
}
/**
* تحليل الاسم والسكويد ومعلومات السعر في صفحة المنتج
* @paramdoc
* @يعود
*/
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>();
ل(السلسلة: ss){
String string=it.replaceAll("/"", "");
إذا (string.contains("//u"))
string=unicodeDecode(string);
String[] str=string.split(":);
hm.put(str[0], str[1]);
}
Util.println(hm);
العودة جلالة؛
}
/**
* معالجة أحرف Unicode وتحويلها إلى أحرف عرض (الأحرف الصينية)، وهي ليست متعددة الاستخدامات.
* @param it: /u6a5d
* @يعود
*/
public static String unicodeDecode(String it){// أحد العيوب هو أنه لا يمكن إزالة الأحرف السابقة
Util.println(it);
سلسلة regex = "(////u[0-9a-f]{4})";
Pattern pt= Pattern.compile(regex);
ماتشر مولودية؛
StringBuffer sb;
StringBuffer sba=new StringBuffer();
mc=pt.matcher(it);
بينما(mc.find()){
sb=new StringBuffer();
mc.appendReplacement(sba,sb.append((char )Integer.parseInt((mc.group(1).substring(2))), 16)).toString());
}
إرجاع sba.toString();
}
/**
* إرجاع كائن المستند (تنزيل المحتوى)
* @param صفحة تنزيل عنوان url
* @يعود
* @throws ClientProtocolException
* @throwsIOException
*/
المستند العام الثابت لأسفل (سلسلة عنوان url) يطرح ClientProtocolException، IOException {
المستند doc = null;
DefaultHttpClient httpClient=new DefaultHttpClient();
Util.println("التحميل:"+url);
HttpGet get=new HttpGet(url);
استجابة HttpResponse؛
الاستجابة = httpClient.execute(get);
كيان HttpEntity = Response.getEntity();
doc = Jsoup.parse(entity.getContent(), "utf-8"،"");
// الافراج عن الموارد
EntityUtils.consume(entity);
// أغلق الاتصال
httpClient.getConnectionManager().shutdown();
وثيقة العودة؛
}
/**
* أضيفت معلومات التحكم في الترميز
* @param صفحة url ليتم تنزيلها
* @param ترميز الكود
* @يعود
* @throws ClientProtocolException
* @throwsIOException
*/
المستند العام الثابت لأسفل (عنوان URL للسلسلة، رمز السلسلة) يطرح ClientProtocolException، IOException {
المستند doc = null;
DefaultHttpClient httpClient=new DefaultHttpClient();
Util.println("التحميل:"+url);
HttpGet get=new HttpGet(url);
استجابة HttpResponse؛
الاستجابة = httpClient.execute(get);
كيان HttpEntity = Response.getEntity();
doc = Jsoup.parse(entity.getContent(), code"");
// الافراج عن الموارد
EntityUtils.consume(entity);
// أغلق الاتصال
httpClient.getConnectionManager().shutdown();
وثيقة العودة؛
}
/**
* يستخدم لتحليل روابط المنتج (المجموعة) في صفحات بيع الفلاش
* @paramdoc
* @يعود
*/
ArrayList العام الثابت<String> getMainUrl(Document doc){
إذا (doc.equals("")||doc==null)
عودة فارغة؛
يحاول {
Thread.sleep(50);
} التقاط (InterruptedException e1) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
e1.printStackTrace();
}
ArrayList<String> urls=new ArrayList<String>();
سلسلة القاعدة = "خريطة [اسم = خريطة] > منطقة [href ~ = المنتج]"؛
/**
* البدء في التحليل
*/
Elements=doc.select(rule);
لـ (العنصر e : العناصر) {
//Util.println(e.absUrl("abs:href"));
urls.add(e.absUrl("abs:href"));
}
إرجاع عناوين URL؛
}
/**
* الحصول على مفتاح skuidkey للاستعلام عن معلومات مخزون المنتج
* @param URL
* @يعود
*/
سلسلة ثابتة عامة parseSkuidkey(String url){
المستند doc=null;
يحاول {
doc=down(url,"gb2312");
} قبض على (ClientProtocolException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
//Util.println(doc.select("script"));
نص السلسلة = فارغ؛
for(العنصر e : doc.select("script")){
إذا(e.data().contains("skuidkey:")){
text=e.data();
استراحة؛
}
}
//مفتاح skuid:'7D45919EA8242511DAA5CC7C6D7B351C'
text=text.substring(text.indexOf("skuidkey:")+10, text.indexOf("skuidkey:")+42);
Util.println("---------------------------------");
Util.println(نص);
إرجاع النص؛
}
/**
* عرض معلومات المخزون
* @param skuidkey
* @يعود
*/
public static boolean hasStore(String skuidkey){// لم تتم معالجة هذا المكان، قم باستخراج المعلومات مباشرة في المتصفح
عنوان السلسلة = فارغ؛
boolean hasStore=false;
إذا (skuidkey!=null &&!"".equals(skuidkey))
عنوان = "http://price.360buy.com/stocksoa/StockHandler.ashx?callback=getProvinceStockCallback&type=pcastock&skuid="+skuidkey+"&provinceid=1&cityid=2800&areaid=2850";
آخر{
Util.println("خطأ في تحليل مفتاح skuid");
}
يحاول {
إذا(parseStore(أسفل(العنوان))){
hasStore=true;
}
} قبض على (ClientProtocolException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
} قبض (IOException ه) {
// TODO كتلة الالتقاط التي تم إنشاؤها تلقائيًا
printStackTrace();
}
إرجاع hasStore;
}
/* إذا(array[1]=="34"||array[1]=="18"){
ChangeCart(false);
djdarea.stockInfoDom.html("<strong class='store-over'>نفاد المخزون</strong>");
}
آخر إذا(صفيف[1]====0"){
ChangeCart(false);
djdarea.stockInfoDom.html("<strong class='store-over'>نفاد المخزون</strong>");
}
وإلا إذا(array[2]=="0"&&array[4]!="2"){
ChangeCart(false);
djdarea.stockInfoDom.html("عذرًا، لا يمكن تسليم هذا المنتج إلى المنطقة التي حددتها");
}
وإلا إذا(array[1]=="33"||array[1]=="5"){
ChangeCart(true);
djdarea.stockInfoDom.html("<strong>Spot</strong>"+(array[4]=="1"؟", المنطقة"+(array[3]=="0"؟"No": ")+"دعم الدفع نقدًا عند التسليم":")+cashdesc);
}
آخر إذا(صفيف[1]====36"){
ChangeCart(true);
djdarea.stockInfoDom.html("<strong>الحجز</strong>"+(array[4]=="1"؟", المنطقة"+(array[3]=="0"؟"No": ")+"دعم الدفع نقدًا عند التسليم":")+cashdesc);
}
آخر إذا(صفيف[1]====39"){
ChangeCart(true);
djdarea.stockInfoDom.html("<strong>في النقل</strong>"+(array[4]=="1"؟", المنطقة"+(array[3]=="0"؟"No": " ")+"دعم الدفع نقدًا عند التسليم":")+cashdesc);
}
آخر إذا(صفيف[1]====40"){
ChangeCart(true);
djdarea.stockInfoDom.html("<strong>متاح للتوزيع</strong>"+(array[4]=="1"؟", هذه المنطقة"+(array[3]=="0"؟"No" :"")+"دعم الدفع نقدًا عند التسليم":")+cashdesc);
}
*/
/**
* تحليل معلومات المخزون
* @paramdoc
* @يعود
*/
مخزن التحليل المنطقي العام الثابت(Document doc){
String text=doc.text();
String docc=text.substring(text.indexOf("-")-1,text.lastIndexOf("،")-1);
Util.println(doc);
String[] store=docc.split("-");
إذا(store[1].equals("34") || store[1].equals("18")){
//إنتهى من المخزن
Util.println("نفاد المخزون هنا");
عودة كاذبة.
}else if(store[1].equals("33") || store[1].equals("5")){
// بقعة البضائع
Util.println("متوفر هنا");
عودة صحيحة؛
}
Util.println(store[1]);
عودة كاذبة.
}
// عدة طرق للفاصوليا
الحصول على تعويم عام () {
سعر العودة
}
مجموعة الفراغ العام (السعر العائم) {
this.price = السعر;
}
الحصول على تعويم عام () {
خصم العودة؛
}
مجموعة الفراغ العام (الخصم العائم) {
this.discount = الخصم؛
}
}
oenCMD.java
انسخ رمز الكود كما يلي:
view.Util;
الطبقة العامة oenCMD {
// عام static void main(String[] args) {
//// openWinExe(null);
// openExe(null,"http://www.baidu.com");
// }
// استخدم Java لاستدعاء ملف exe الخاص بنظام Windows، مثل المفكرة والحساب وما إلى ذلك.
public static void openWinExe(String command,String url) {
إذا(command==null ||command.equals("")){
الأمر = "الكروم"+url;
}
Runtime rn = Runtime.getRuntime();
العملية ع = فارغة؛
يحاول {
ع = rn.exec(command);
} قبض (الاستثناء ه) {
System.out.println("حدث خطأ أثناء فوز exec!");
}
}
// اتصل بالملفات القابلة للتنفيذ الأخرى، مثل exe الذي أنشأته بنفسك، أو البرامج التي تم تنزيلها وتثبيتها.
public static void openExe(String pathAndName,String url) {
إذا (pathAndName==null || pathAndName.equals("")){
pathAndName="C://Users//Administrator//AppData//Local//Google//Chrome//Application//chrome.exe";
}
إذا(url!=null && !url.equals("")){
pathAndName+=" ";
pathAndName+=url;
}
Runtime rn = Runtime.getRuntime();
العملية ع = فارغة؛
يحاول {
p = rn.exec(pathAndName);
} قبض (الاستثناء ه) {
System.out.println("خطأ تنفيذي!");
}
}
}