本文作者:DurkBlue

微信公众号实时抓取

DurkBlue2019-12-272245
微信公众号实时抓取摘要: 很多业务可能都会抓取微信公众号。而有些时候由于对方app或者我们技能的限制,导致并不能简单的脱壳处理。今天我们换一种思路进行公众号抓取。抓取思路整理使用Appium自动化控制手机,...

很多业务可能都会抓取微信公众号

而有些时候由于对方app或者我们技能的限制,导致并不能简单的脱壳处理。

今天我们换一种思路进行公众号抓取。

抓取思路整理

使用Appium自动化控制手机,模拟用户对微信公众号列表进行相关操作

使用mitmproxy中间人代理拦截内容,解析出公众号列表页

使用python对公众号内容进行抓取

源码地址

微信公众号抓取项目地址


关键源码解析

appium部分。首先我们需要找出每个界面所对应的Activity和每个Activity界面的按钮。


from appium import webdriver

import time

from selenium.webdriver.support import expected_conditions as EC

from appium.webdriver.common.touch_action import TouchAction

from selenium.webdriver.common.by import By

from selenium.webdriver.support.wait import WebDriverWait

desired_caps={

  "platformName": "Android",

 "deviceName": "a",

  "appPackage": "com.tencent.mm",

  "appActivity": "com.tencent.mm.ui.LauncherUI",

    'noReset':True

}

url = 'http://localhost:4723/wd/hub'


driver = webdriver.Remote(url,desired_capabilities=desired_caps)

driver.wait_activity('.ui.LauncherUI',timeout=10)

WebDriverWait(driver, 10).until(

        EC.presence_of_element_located((By.XPATH, '//*[@text="通讯录"]'))

    ).click()

driver.find_element_by_xpath('//*[@text="公众号"]').click()

driver.wait_activity('.plugin.brandservice.ui.BrandServiceIndexUI',timeout=10)

while True:

    try:

      items = driver.find_elements_by_xpath('//*[@resource-id="com.tencent.mm:id/a2y"]')

      for item in items:

            item.click()

            driver.wait_activity('.ui.chatting.ChattingUI',timeout=10)

            driver.find_element_by_id('com.tencent.mm:id/jy').click()

            driver.wait_activity('.plugin.profile.ui.ContactInfoUI',timeout=10)

            # driver.find_element_by_id('com.tencent.mm:id/b0u').click()

            TouchAction(driver).press(x=569, y=2000).move_to(x=390, y=792).release().perform()

            driver.find_elements_by_xpath('//*[@resource-id="com.tencent.mm:id/b0r"]')[-1].click()

            driver.wait_activity('.plugin.profile.ui.ContactInfoUI', timeout=10)

            driver.back()

            driver.back()

            driver.back()

    except Exception as e:

      pass


    time.sleep(1)



mitm代理中间人代码

import sys

sys.path.append('..')

sys.path.append('../..')

sys.path.append('../../..')

import re

import redis


from wechat.settings import QUEUES


QUEUE_CONF = QUEUES['tasks']

r = redis.Redis(**QUEUE_CONF)


class WeChatProxyHandler():

    url = 'https://mp.weixin.qq.com/mp/profile_ext?action=home'

    def response(self,flow):

        if (flow.request.url.find(self.url))!=-1:

            for line in flow.response.text.split('\n'):

                line = line.strip()

                if line.find('var msgList') != -1:

                    line = eval(re.sub('"', '"', line[len('var msgList = ') + 1:-2]))

                    urls = [item.get('app_msg_ext_info', {}).get('content_url') for item in line['list']]

                    urls = [re.sub('\\\/', '/', url) for url in urls if url]

                    r.lpush('wechat', *urls)

addons=[

    WeChatProxyHandler()


总结

中间人代理可以帮助我们做很多事情

使用splash的时候可以把请求耗时的内容给拦截掉

通过js注入,可以实现自动分页抓取

这篇文章由DurkBlue发布,转载请注明来处
文章投稿或转载声明

来源:DurkBlue版权归原作者所有,转载请保留出处。本站文章发布于 2019-12-27
温馨提示:文章内容系作者个人观点,不代表DurkBlue博客对其观点赞同或支持。

赞(0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享