2025年3月31日 星期一 乙巳(蛇)年 正月初一 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

薅羊毛 | Python 自动化带你轻松赚钱(完结版)

时间:10-12来源:作者:点击数:34
城东书院 www.cdsy.xyz

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
  •     img_height = size[0]
  •     img_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(25))
  •          # 滑动一次
  •          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、结 果 结 论

通过以上的步骤,即可以完成自动化挑选商品、浏览、购买等一系列操作。

需要补充的是,由于手机分辨率的不一致,导致商品主图匹配会存在一定的误差;但由于主图宽、高比是一致的,可以通过缩放图片达到适配的目的。

已经将全部源码,包含文中使用的APK上传:https://github.com/xingag/app_spider/tree/master/scalp。

城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐