爬虫-uiautomator2获取拼多多APP端商品数据

        本章将对拼多多APP端进行自动化爬虫,由于发现现在的文章对APP爬虫的介绍少之又少,因此本文也会详细地介绍APP自动化工具库uiautomator2和辅助工具weditor。

注意:

  • 本文将默认已经配置了abd、ATX以及一系列必要的设备,下午只讲思路以及实现方法,并没有介绍到如何按照测试环境,若有需要将于日后发布环境配置的文章。

1、启动Weditor

        执行weditor:命令行运行python -m weditor

        

随后将会自动打开一个网页,即我们的辅助工具

网页上的任何元素都可以通过左侧点击方式得到它所在位置的Hierarchy(类似于web的xpath)

2、python利用uiautomator2库连接上设备

        由于uiautomator库的操作非常简单,这里就不赘述了,设置连接方式和连接以及要采集的商品数量:

class PDD:
    def __init__(self, shop, devices, account):
        """
        初始化PDD类,连接到设备并设置店铺名称。

        :param shop: 店铺名称
        :param devices: 设备的IP地址或序列号
        :param account: 要获取的商品数量
        """
        self.shop_name = shop
        self.device = u2.connect(devices) #连接上手机并返回给debvice
        self.account = account

3、对pdd数据进行搜索和采集

        3.1搜索进入商品界面

这里我们先观察pdd界面,观察它搜索框的位置,可以看到它的定位有text,resourceld的方式,但由于text情况并不稳定,因此我们采用resourceId的定位方式,点击搜索框元素

pdd这里需要点击搜索后跳到下一页面后才能继续输入,之后要输入商品名称并且点击搜索按钮。因此从界面到搜索的方法可以这么写

​
    def __search(self):
        """
        在设备上执行搜索操作。
        """
        self.device(resourceId='com.xunmeng.pinduoduo:id/pdd').click()
        self.device.send_keys(self.shop_name)
        self.device(text='搜索').click()
        time.sleep(1)

​

运行代码后的页面为:

这里可以看到我们已经点入进来了

3.2循环点击商品进入详情页

接下来我们该对商品进行点击,进入到特定的商品详情页后。会发现每一个模块的的位置,因此在原理上可以通过模块定位。由于手机页面仅能显示6个,所以android.widget.FrameLayout这个元素也只有6个。

理论上可以用这个方法来定位到块元素,并且通过点击的方式进入到商品的详情页。但是并不是很推荐,一:速度太慢。二:容易重复点击。因此我们采用关键字的方式来定位元素的位置(类似于网页端的//*[contains(text(), '文本内容')]。

这里我们采用定位¥这个符号,因此该符号每一个页面都有,并且为了预防会出现重复点击的事件发生,我们讲元素定位到价格,采用定位¥元素的兄弟节点,并且记录兄弟节点的方式,以此达到不会重复点击的目的

但点击进入页面之后,为了表现出循环的方式,因此还添加点击返回的操作。以下是便利点击的代码:

    def __slide(self):
        """
        滑动浏览页面,并获取符合条件的商品详细信息。
        """
        temp_account = 0
        recent_elements = []
        while 1:
            elems = self.device.xpath('//*[contains(@text, "¥")]/following-sibling::*[1]').all()
            for elem in elems:
                if elem.text and elem.text not in recent_elements:
                    if len(recent_elements) >= 3:
                        recent_elements.pop(0)  # 移除最早添加的元素
                    recent_elements.append(elem.text)
                    elem.click()
                    #操作
                    self.get_detail()
                    # 返回到上一级页面
                    self.device.xpath(
                        '//*[@content-desc="顶部工具栏"]/android.widget.RelativeLayout[1]/android.widget.FrameLayout[1]').click()
                if temp_account > self.account:
                    return recent_elements
                print(recent_elements)
                temp_account += 1  # 将该行移动到这里,确保每次处理都会增加计数器
            self.device.swipe_ext("up", 0.5)
            print('next')
            time.sleep(3)

3.3获取商品信息(配合3.2实现循环获取)

进行了点击之后,我们讲进入如下的界面:

为了能够采集到数据,我们也采用Ui定位的方式来得到指定的元素内容(方式如上述一样,这里就不赘述了,直接显示代码),这里我们抓取了商品的价格,标题以及店铺名称

    def __get_detail(self):
        """
        获取商品的详细信息,包括价格、标题和店名。

        :return: 包含商品详细信息的字典
        """
        detail = {}
        # 获取价格
        price = ''
        price_elements = self.device.xpath(
            '//*[@resource-id="android:id/content"]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[2]').child(
            '//*').all()
        for elem in price_elements:
            if elem.text:
                price += elem.text
        detail['price'] = price

        # 获取标题
        title_elements = self.device.xpath(
            '//android.support.v7.widget.RecyclerView/android.widget.LinearLayout[3]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]').child(
            '//android.widget.TextView').all()
        real_title = ''.join([elem.text for elem in title_elements if elem.text])
        detail['real_title'] = real_title

        # 向上滑动页面以获取更多内容
        self.device.swipe_ext("up", 1)

        # 获取店名
        store = ''
        store_name_elements = self.device.xpath(
            '//*[@resource-id="android:id/content"]/android.widget.FrameLayout[1]/android.support.v7.widget.RecyclerView[1]').child(
            '//*').all()
        for elem in store_name_elements:
            if '专营店' in elem.text or '旗舰店' in elem.text:
                store = elem.text
        detail['store'] = store
        return detail

4、运行结果:

这里我们抓取了商品价格,商品标题以及店铺名称的元素

需要源码请私信我

ILDD

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值