美文网首页
5. 短视频App数据抓取

5. 短视频App数据抓取

作者: BeautifulSoulpy | 来源:发表于2020-12-16 21:41 被阅读0次

    5-1 抖音短视频抓取需求分析

    1.需求分析
    1.1 模拟滑动视频和发布者点击发布者

    1.2 通过mitmproxy抓取并解析数据
    import uiautomator2 as u2
    import time
    
    class Douyin(object):
        def __init__(self, serial="192.168.0.101"):
            # 连接
            self.d = u2.connect(serial)
            # 调用方法
            self.start_app()        # 启动
            self.handle_watcher()  # 监控器
            self.size = self.get_windowsize()
            # 获取初始时间
            self.t0 = time.perf_counter()
    
        def start_app(self):
            self.d.app_start(package_name="com.ss.android.ugc.aweme")
    
        def stop_app(self):
            """退出逻辑"""
            self.d.watcher.stop()
            self.d.app_stop("com.ss.android.ugc.aweme")
            self.d.app_clear("com.ss.android.ugc.aweme")
    
    
    
        def stop_time(self):
            if time.perf_counter() - self.t0 > 20:  # s
                return True
    
        def handle_watcher(self):
            # 通知权限
            self.d.watcher.when('//*[@resource-id="com.ss.android.ugc.aweme:id/a4r"]').click()
            # 发现滑动查看更多
            self.d.watcher.when('//*[@text="滑动查看更多"]').click()
            self.d.watcher.when('//*[@text="快速进入TA的个人中心"]').click()
            self.d.watcher.start(interval=1)
    
        def get_windowsize(self):
            return self.d.window_size()
    
    
        def swipe_douyin(self):
            '''滑动抖音短视频 点击视频发布者头像的操作'''
            # 判断是否正常进入抖音界面
            if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists(timeout=20):
                while True:
                    if self.stop_time():
                        self.stop_app()
                        return
    
                    # 查看 是不是正常的发布者(不是广告)
                    if self.d(resourceId="com.ss.android.ugc.aweme:id/u0").exists:
                        # 是不是正常的 发布者,点击头像
                        self.d(resourceId="com.ss.android.ugc.aweme:id/tw").click()
                        # 返回
                        self.d(resourceId="com.ss.android.ugc.aweme:id/et").click()
    
                    # 判断是否正常进入抖音界面
                    if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists:
                        # 滑动: 由下向上滑动;
                        x1 = int(self.size[0]*0.5)
                        y1 = int(self.size[1]*0.9)
                        y2 = int(self.size[1]*0.15)
                        self.d.swipe(x1, y1, x1, y2)
    
    if __name__ == '__main__':
        d = Douyin()
        d.swipe_douyin()
    
    

    5-6 通过mitmproxy解析短视频App返回数据-接口分析

    先保证WIN和手机IP地址的一致性


    确保 手机上安装fiddle证书

    先点掉 Capturing, 抓取的数据包就是连到手机上的数据包


    有两个JS文件,先看第一个
    特别注意

    在新版本的抖音里,我们是找到的是加密的数据返回;低版本在豌豆荚中可以下载,得到没有加密的数据;


    # 个人信息页接口
    # https://aweme-eagle.snssdk.com/aweme/v1/user/?user_id
    
    # 滑动视频接口
    # https://aweme-eagle.snssdk.com/aweme/v1/feed
    
    1. 个人信息页接口

    第一个JS文件


    # json格式文件
    
    "wx_nickname_replace":"开心锤锤♪","replaced":false},
    "ky_only_predict":0,"school_auth":0,"is_star":false,"general_permission":{"following_follower_list_toast":1},
    "share_weibo_desc":"在抖音,记录美好生活!","share_desc":"在抖音,记录美好生活!",
    "share_title":"快来加入抖音,让你发现最有趣的我!","share_qrcode_url":{"uri":"671f001b2afba0ae78dc","url_list":["https://p9-dy.byteimg.com/obj/671f001b2afba0ae78dc","https://p6-dy-ipv6.byteimg.com/obj/671f001b2afba0ae78dc","https://p3-dy-ipv6.byteimg.com/obj/671f001b2afba0ae78dc"]}},"activity":{"use_music_count":0,"digg_count":0},"follower_status":0,"duet_setting":0,"unique_id":"2B2B2","geofencing":
    
    
    
    2. 滑动视频接口

    点击 滑动按钮,重新抓取数据;


    5-7 通过mitmproxy解析短视频App返回数据-编写mitmdump解析文件

    确保安装好了手机mitmproxy 以及证书(IP变化就要重新安装)

    # decode_douyin.py
    import json
    
    def response(flow):
        """解析10版本抖音app返回数据"""
        # 视频
        if 'https://aweme-eagle.snssdk.com/aweme/v1/feed' in flow.request.url:
            # 使用json来loads response.text
            video_response = json.loads(flow.response.text)
            video_list = video_response.get("aweme_list", [])
            for item in video_list:
                print(item.get("desc"), "")   # 视频标题
    
        # 发布者页面
        if 'https://aweme-eagle.snssdk.com/aweme/v1/user/?user_id' in flow.request.url:
            person_response = json.loads(flow.response.text)
            person_info = person_response.get("user", "")
            if person_info:
                info = {
                    'nickname': person_info.get("nickname", ""),   # 名称
                    'total_favorited': person_info.get("total_favorited", 0),  # 点赞数
                    'following_count': person_info.get("following_count", 0),  # 关注着数量
                    'douyin_id': person_info.get("unique_id", ""),               # 抖音ID
                    'folllower_count': person_info.get("follower_count", 0)    # 粉丝数量
                }
                print('--------------------------------------------------------------------')
                print(info)
    
    
    

    启动 mitmdump

    (venv) user1@imooc:~/u2_project/douyin$ mitmdump -s decode_douyin.py -p 8889
    Loading script decode_douyin.py
    Proxy server listening at http://*:8889
    
    # run handle_douyin.py
    import uiautomator2 as u2
    import time
    
    class Douyin(object):
        def __init__(self, serial="192.168.0.101"):
            # 连接
            self.d = u2.connect(serial)
            # 调用方法
            self.start_app()        # 启动
            self.handle_watcher()  # 监控器
            self.size = self.get_windowsize()
            # 获取初始时间
            self.t0 = time.perf_counter()
    
        def start_app(self):
            self.d.app_start(package_name="com.ss.android.ugc.aweme")
    
        def stop_app(self):
            """退出逻辑"""
            self.d.watcher.stop()
            self.d.app_stop("com.ss.android.ugc.aweme")
            self.d.app_clear("com.ss.android.ugc.aweme")
    
        def stop_time(self):
            if time.perf_counter() - self.t0 > 20:  # s
                return True
    
        def handle_watcher(self):
            # 通知权限
            self.d.watcher.when('//*[@resource-id="com.ss.android.ugc.aweme:id/a4r"]').click()
            # 发现滑动查看更多
            self.d.watcher.when('//*[@text="滑动查看更多"]').click()
            self.d.watcher.when('//*[@text="快速进入TA的个人中心"]').click()
            self.d.watcher.start(interval=1)
    
        def get_windowsize(self):
            return self.d.window_size()
    
    
        def swipe_douyin(self):
            '''滑动抖音短视频 点击视频发布者头像的操作'''
            # 判断是否正常进入抖音界面
            if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists(timeout=20):
                while True:
                    if self.stop_time():
                        self.stop_app()
                        return
    
                    # 查看 是不是正常的发布者(不是广告)
                    if self.d(resourceId="com.ss.android.ugc.aweme:id/u0").exists:
                        # 是不是正常的 发布者,点击头像
                        self.d(resourceId="com.ss.android.ugc.aweme:id/tw").click()
                        # 返回
                        self.d(resourceId="com.ss.android.ugc.aweme:id/et").click()
    
                    # 判断是否正常进入抖音界面
                    if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists:
                        # 滑动: 由下向上滑动;
                        x1 = int(self.size[0]*0.5)
                        y1 = int(self.size[1]*0.9)
                        y2 = int(self.size[1]*0.15)
                        self.d.swipe(x1, y1, x1, y2)
    
    if __name__ == '__main__':
        d = Douyin()
        d.swipe_douyin()
    
    
    --------------------------------------------------------------------
    {'nickname': '七猫探长', 'total_favorited': 4012853, 'following_count': 89, 'douyin_id': 'qimao2021', 'folllower_count': 550240}
    

    实战2:小红书

    1.抓取需求分析

    抓取 推荐也文章基本信息(文章标题、类型、基本描述、用户信息等)

    文章详细内容

    文章评论

    2. 滑动视频接口
    import uiautomator2 as u2
    import time, datetime
    import adbutils, multiprocessing
    from elasticsearch import Elasticsearch, helpers
    
    es = Elasticsearch(hosts="192.168.0.101:9200")
    class Xiaohongshu(object):
        def __init__(self, serial="192.168.0.103:5555"):
            '''
            手机IP:192.168.0.103
            Linux系统IP : 192.168.0.101
            desc: V1:刷新新的内容, V2:下一版本功能:爬取文章详细内容和评论数
            :param serial:
            '''
            self.d = u2.connect(serial)
            self.size = self.get_window_size()
            self.start_app()
    
    
        def start_app(self, name='com.xingin.xhs'):
            self.d.app_start(package_name=name)
    
        def get_window_size(self):
            return self.d.window_size()
    
        def swipe_screen(self):
            x1 = int(self.size[0] * 0.5)
            y1 = int(self.size[1] * 0.9)
            y2 = int(self.size[1] * 0.25)
            self.d.swipe(x1, y2, x1, y1)
    
    
    if __name__ == '__main__':
        d = Xiaohongshu()
        time.sleep(3)
        flag = True
        while flag:
            d.swipe_screen()
            # time.sleep(1)
        print(es.search(index="xiaohongshu_2021-03-17"))
    
    
    3.mitmproxy解析短视频App返回数据
    import json
    import time
    import datetime
    
    from elasticsearch import Elasticsearch, helpers
    
    es = Elasticsearch(hosts="192.168.0.101:9200")
    
    def handle_date(key):
        """处理时间方法"""
        date_touple = time.localtime()
        date = None
        if key == "hms":
            date = time.strftime("%Y-%m-%d %H:%M:%S", date_touple)
            date = date.replace(' ', 'T')
        elif key == "bir":
            date = time.strftime("%Y-%m-%d", date_touple)
        return date
    
    
    def response(flow):
        '''
        解析 小红书 最新版本 app 的 目录页数据;
        每次滑动拿到 10条数据;
        '''
    
        if 'https://edith.xiaohongshu.com/api/sns/v6/homefeed' in flow.request.url:
            article_response = json.loads(flow.response.text)
    
            article_list = article_response.get('data', [])
            data_list = []
            for item in article_list:
                info ={
                    "_index": "xiaohongshu_%s" % handle_date(key="bir"),
                    "_source": {
                        "@timestamp": handle_date(key="hms"),
                        "birthday": handle_date(key="bir"),
                        "title": item.get("display_title", ""),
                        "name": item.get("user", "").get("nickname", ""),
                        "userid": item.get("user", "").get("userid", ""),
                        "type": item.get("type", ""),
                        "display_image":item.get("images_list", "").get("url_size_large", "")
                        "desc": item.get("desc", ""),
                        "likes": item.get("likes", "")
                    }
                }
                print(info)
                data_list.append(info)
            # 通过helpers插入数据
            helpers.bulk(es, data_list)
    
    
    
    5. 查看10分钟爬取效果

    3284/10m

    get xiaohongshu_2021-03-17/_search
    #---------------------------------------------------------
    {
      "took" : 2,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3284,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "xiaohongshu_2021-03-17",
            "_type" : "_doc",
            "_id" : "4d3sPXgBy2dlyd-YuFIb",
            "_score" : 1.0,
            "_source" : {
              "@timestamp" : "2021-03-17T10:03:47",
              "birthday" : "2021-03-17",
              "title" : "考研复试简历模板大放送,请查收㊙️",
              "name" : "研学长",
              "userid" : "5d8f85a600000000010036ac",
              "type" : "normal",
              "desc" : """🌈哈喽,各位21/22考研的小伙伴们
    ❤️在考研复试中,我们为了让导师更加快速全面的了解我们,通常都需要准备一份精美的简历进行自我介绍,一份好的模板通常能让导师对你有更好的印象与了解!也是你个人形象的""",
              "likes" : 5813
            }
          },
    
    

    注意
    1.解决kibana 超过10000条数据无法查询的问题

    get xiaohongshu_2021-03-17/_settings
    {
      "max_result_window" : 200000000
    } 
    
    

    相关文章

      网友评论

          本文标题:5. 短视频App数据抓取

          本文链接:https://www.haomeiwen.com/subject/eagwgktx.html