欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python3WebSpider_Appium爬取微信朋友圈

程序员文章站 2022-07-12 22:16:09
...

Appium爬取微信朋友圈

  • 用Appium实现微信朋友圈动态信息抓取,主要包括好友昵称、正文、发布时间;其中正文这一部分我并没有爬取下来;
1、准备工作
2、爬取思路
  • (1)初始化配置,如驱动配置,MongoDB连接配置等
class Moments():
    def __init__(self):
        """
        初始化
        """
        # 驱动配置
        self.desired_caps = {
            'platformName': PLATFORM,
            'deviceName': DEVICE_NAME,
            'appPackage': APP_PACKAGE,
            'appActivity': APP_ACTIVITY,
            'noReset': "True"
        }
        self.driver = webdriver.Remote(DRIVER_SERVER, self.desired_caps)
        self.client = MongoClient(MONGO_URL)
        self.db = self.client[MONGO_DB]
        self.collection = self.db[MONGO_COLLECTION]
        # 处理器
        self.processor = Processor()
  • (2)模拟登陆,由于我在Appium驱动配置上加了参数:‘noReset’: “True”;数据不重置,所以模拟登陆这一步可以直接跳过,只要微信是登陆的,代码运行的时候就是直接在已登录状态中;
  • (3)直接选择发现选项卡→朋友圈进入;
    def enter(self):
        """
        进入朋友圈
        :return:
        """
        # 选项卡
        time.sleep(15)
        tab = self.driver.find_elements(By.XPATH, '//*[@resource-id="com.tencent.mm:id/r4"]')[2]
        tab.click()
        time.sleep(15)
        # 朋友圈
        moments = self.driver.find_element(By.ID, 'android:id/title')
        moments.click()
        print("已进入朋友圈")
  • (4)抓取动态,由于朋友圈需要拖动,才能看到更多内容,所以,这里需要模拟一个拖动的操作,进行循环;driver.swipe(300,1000,300,300);首先获取点前显示的朋友圈的每条状态对应的区块元素,遍历每个区块元素,再获取内部显示的用户名,和发布时间;
    def crawl(self):
        """
        爬取
        :return:
        """
        for i in range(15):
            time.sleep(2)
            # 上滑
            self.driver.swipe(300, 1000, 300, 300)
            # 当前页面显示的所有状态
            items = self.driver.find_elements(By.XPATH, '//*[@resource-id="com.tencent.mm:id/ej_"]')
            # 遍历每条状态
            for item in items:
                try:
                    # 昵称
                    nickname = item.find_element(By.XPATH, '//*[@resource-id="com.tencent.mm:id/b5o"]').get_attribute('text')
                    # # 正文
                    # content = item.find_element(By.XPATH, '//*[@resource-id="com.tencent.mm:id/kt"]').get_attribute('text')
                    #
                    # 日期
                    date = item.find_element(By.XPATH, '//*[@resource-id="com.tencent.mm:id/eec"]').get_attribute('text')
                    # 处理日期
                    date = self.processor.date(date)
                    print(nickname, date)
                    data = {
                        'nickname': nickname,
                        # 'content': content,
                        'date': date,
                    }
  • (5)对于时间显示几小时前或者几分钟前的,我们用正则匹配的方法来提取时间中的具体数值,再利用时间转换函数实现时间的转换;例如5分钟前,这个方法先将5提取出来,用当前时间戳减去300即可得到发布的时间戳,然后再转换为标准时间即可。
class Processor():
    def date(self, datetime):
        """
        处理时间
        :param datetime: 原始时间
        :return: 处理后时间
        """
        if re.match('\d+分钟前', datetime):
            minute = re.match('(\d+)', datetime).group(1)
            datetime = time.strftime('%Y-%m-%d', time.localtime(time.time() - float(minute) * 60))
        if re.match('\d+小时前', datetime):
            hour = re.match('(\d+)', datetime).group(1)
            datetime = time.strftime('%Y-%m-%d', time.localtime(time.time() - float(hour) * 60 * 60))
        if re.match('昨天', datetime):
            datetime = time.strftime('%Y-%m-%d', time.localtime(time.time() - 24 * 60 * 60))
        if re.match('\d+天前', datetime):
            day = re.match('(\d+)', datetime).group(1)
            datetime = time.strftime('%Y-%m-%d', time.localtime(time.time()) - float(day) * 24 * 60 * 60)
        return datetime
  • (6)最后调用MongoDB的API来实现爬取结果的存储。为了去除重复,这里调用了update()方法,这个操作的关键点事第三个参数True,此参数设置为True,可以实现存在即更新。不存在则插入的操作实现如下所示:
self.collection.update_one({'nickname': nickname}, {'$set': data}, True)

Python3WebSpider_Appium爬取微信朋友圈