首頁>科技>

1

目 標 場 景

最近,有一個朋友告訴我,她在某平臺上購買了一部手機,收到貨之後發現商品品質挺好的,價格也不貴。

臨了隨手給了個好評,商家最後還給她發一個 小紅包,她把這個商品分享給了我。

本篇文章的目的是利用 Python 自動化完成商品購買的操作。

ps:本文僅限用於技術交流,請勿用於其他用途。

2

準 備 工 作

在編寫程式碼之前,需要做如下準備工作:

1、配置好 Android ADB 開發環境

2、Python 虛擬環境內安裝 pocoui 依賴庫

3、操作剪下板的應用 APK,下載連結見文末

3

編 寫 代 碼

我們分 7 個步驟來實現這個功能,分別是:開啟目標應用客戶端、搜尋關鍵字到商品列表介面、裁剪原圖拿到商品主圖、商品匹配、商品收藏和瀏覽、購買商品、獲取訂單號和截圖。

第 1 步,使用 Airtest 自動化開啟目標應用。

# 目標應用package_name = '應用包名'activity = 'Home Activity'def __pre(self): """ 準備工作 :return: """ # 刪除快取檔案 remove_cache('./part.jpg', './screenshot.png', './uidump.xml') home() stop_app(package_name) start_my_app(package_name, activity)

開啟應用之後,就可以進行第 2 步操作了。

def __search_good_by_key(self): """ 通過關鍵字搜尋商品 :return: """ self.poco(id_page_main_button_search).wait(5).click() perform_view_input(self.poco, id_page_search_edittext_search, self.key) # 點選搜尋 self.poco(id_page_search_button_search).wait_for_appearance() while self.poco(id_page_search_button_search).exists(): print('點選一次搜尋') perform_view_id_click(self.poco, id_page_search_button_search) # 等待列表加載出來 self.poco(id_page_goods_rv).wait_for_appearance()

第 3 步,剪下原圖,需要對原圖中多餘的白色區域進行刪除,只保留左側的商品主圖。

通過 遍歷 x 軸、y 軸,拿到每一個畫素的顏色值,如果是連續的白色就做一個標識,進而拿到主圖的上、下、左、右座標值,最後利用 cv2 庫進行裁剪,得到商品主圖。

def crop_main_img(img_path): """ 獲取商品主圖 :return: """ img = cv2.imread(img_path) # 圖片大小(高、寬、the pixels value is made up of three primary colors) size = img.shape height = size[0] width = size[1] channels = size[2] # 1080*458 print(f'圖片寬度:{img_width},高度:{img_height}' # 標識陣列,針對x軸和y軸 arr_x = [] arr_y = [] # 遍歷寬,得到主圖的x軸座標 for x in range(img_width): is_black = True # 遍歷高 for y in range(img_height): # 獲取顏色值 color_position = img[y, x] if (color_position == color_white).all(): pass else: is_black = False arr_x.append(is_black) # 遍歷高,得到主圖的y軸座標 for y in range(img_height): is_black = True # 遍歷高 for x in range(img_width): # 獲取顏色值 color_position = img[y, x] if (color_position == color_white).all(): pass else: is_black = False arr_y.append(is_black) position_x = get_space_index(arr_x) position_y = get_space_index(arr_y) main_img_path = "./head_img.jpeg" # 剪下 # 裁剪座標為[y0:y1, x0:x1] cropped = img[position_y[0]:position_y[1], position_x[0]: position_x[1]] cv2.imwrite(main_img_path, cropped) return main_img_path

第 4 步,商品匹配。

拿到商品主圖之後,利用 Airtest 在當前頁面進行元素查詢,如果沒有找到,就滑到下一個元素;否則,就拿到匹配商品的座標。

def __search_good_from_list(self): """ 從列表中匹配商品 :return: """ # 迴圈的圖片查詢 while True: try: pos = loop_find(Template(self.main_img_path), timeout=10, threshold=0.95) except TargetNotFoundError: print('滑動一頁') self.__swipe(True) else: print('找到了') # 螢幕寬度和高度 screen_size = self.poco.get_screen_size() print(screen_size) # 點選的座標點(寬、高) # (0.22407407407407406, 0.8550925925925926) position_click = (pos[0] / screen_size[0], pos[1] / screen_size[1]) print(position_click) self.poco.click(position_click) break

第 5 步,商品收藏和瀏覽。

在預先設定的瀏覽時間內,執行休眠、滑動操作。

def __browser_good_detail(self): """ 瀏覽商品 :return: """ # 切換到詳情Tab self.poco('com.**:id/taodetail_nav_bar_tab_text', text='詳情').click() # 滑動時長為: self.browser_detail_time browser_start = datetime.datetime.now() browser_end = browser_start while (browser_end - browser_start).seconds < self.browser_detail_time: # 休眠一會 time.sleep(random.randint(2, 5)) # 滑動一次 self.__swipe(True) # 結束時間 browser_end = datetime.datetime.now() print('詳情頁面檢視完畢')

第 6 步,購買商品。

def __buy_good(self): """ 購買商品 :return: """ # 立即購買 self.poco('**/detail_main_sys_button', text='立即購買').click() # 選擇商品屬性 sleep(10) # 確定購買 self.poco('**/confirm_text', text='確定').parent().click() # 提交訂單 self.poco(text='提交訂單').click() # 手動輸入密碼或者指紋 sleep(10)

第 7 步,獲取訂單 ID 及商品截圖。

通過 Monitor 觀察發現,訂單號文字元素很難通過屬性或者子、父關係拿到。

可以通過點選複製按鈕,將訂單號貼上到系統的剪下板,然後利用 adb + clipper 這款 App拿到剪下板中的內容。

def __get_order_no(self): """ 獲取訂單編號 :return: """ global copy_element while True: # 由於手機螢幕的限制,【複製】按鈕第一頁不一定能顯示出來 try: copy_element = self.poco(text='複製') except Exception as e: print('沒有找到元素,往下滑動一頁') self.__swipe(True) break # 複製到剪下版本 copy_element.click() # 從剪下板拿到資料 result = exec_cmd('adb shell am broadcast -a clipper.get')[1] # 匹配出訂單號 result = re.findall(r'data="(.*)"', result) order_no = '' if result and len(result) > 0: order_no = result[0] print(order_no) return order_no

接著利用 adb 命令擷取當前螢幕,然後儲存到 PC 端,即完成了全部操作。

def get_order_pic(self): """ 拿到訂單截圖介面 :return: """ screenshot_pic_result = './order_screenshot.png' # 擷取手機當前螢幕 exec_cmd('adb shell /system/bin/screencap -p /sdcard/screenshot.png') # 儲存到PC端 exec_cmd('adb pull /sdcard/screenshot.png %s' % screenshot_pic_result) return screenshot_pic_result

4

結 果 結 論

通過以上的步驟,即可以完成自動化挑選商品、瀏覽、購買等一系列操作。

需要補充的是,由於手機解析度的不一致,導致商品主圖匹配會存在一定的誤差;但由於主圖寬、高比是一致的,可以通過縮放圖片達到 適配 的目的。

1245

Python

最新評論
  • 1 #

    airtest這麼流行了?

  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 這個十月是屬於 PC 的季節