抖音App和服务端交互应用的是HTTPS协定,应用Fiddler很容易能够捕捉到数据,如下图所示。

不过想要本人模仿一个无效的申请可不是那么容易了,因为它应用了签名机制,在所有申请中都有as和cp两个签名参数,除非得悉签名算法否则咱们无奈结构出无效的申请。
这里咱们应用模仿操作抖音App的形式,让App帮咱们收回无效的申请,而后咱们拦挡服务器的HTTP应答数据,再从中提取咱们感兴趣的信息。
上面联合一个理论的案例介绍下整个过程,依据客户的需要,要采集一些指定用户加关后的零碎举荐“你可能感兴趣”的数据(如下图所示)用于商品营销。

点击“查看更多”能够看到更多的零碎举荐用户列表数据,如下图所示。

咱们按如下步骤模仿操作App:
1.启动抖音。
2.点击搜寻按钮。
3.输出搜寻关键词(抖音用户ID),点击搜寻。
4.找到匹配的用户,点击关注。
5.点击零碎举荐“查看更多”,模仿屡次向上滑动屏幕,直至数据加载结束(屏幕呈现“临时没有更多了”)。
于此同时,咱们应用抓包脚本(能够应用Fiddler的Customize Rules,也能够应用Mitmproxy),捕捉并过滤URL中含有/user/recommend/的HTTP应答数据,从JSON数据中提取零碎举荐的用户信息(如下图所示)。
模仿操作抖音App的脚本外围代码如下所示:
view plaincopy to clipboardprint?

from com.dtmilano.android.viewclient import ViewClientdef search_douyin_for_recommend_user(douyin_id):# 采集指定抖音账号的关注举荐数据# 连设施serialno = Noneif serialno:    os.system('adbconnect{}'.format(serialno or ''))    time.sleep(3)    device, serialno = ViewClient.connectToDeviceOrExit(serialno=serialno)    vc = ViewClient(device, serialno, autodump=False)    # 强制敞开抖音      log(u'强制敞开抖音.')    device.shell('am force-stop com.ss.android.ugc.aweme')    time.sleep(2)    # 启动抖音      log(u'启动抖音.')    device.shell('am start -n com.ss.android.ugc.aweme/.main.MainActivity')    time.sleep(5)    # 暂停视频播放      log(u'点击屏幕,暂停视频播放.')    device.touch(514, 1048)    # 点击搜寻按钮      vc.dump()    search_btn = vc.findViewById('com.ss.android.ugc.aweme:id/amj')    if search_btn:        log(u'点击搜寻按钮,跳转到搜寻页面.')        search_btn.touch()        vc.dump()        # 点击搜寻输入框          search_input = vc.findViewById('com.ss.android.ugc.aweme:id/ad_')        if search_input:            log(u'点击搜寻框,筹备输出关键词.')            search_input.touch()            # 输出抖音ID              log(u'输出搜寻关键词: {}.'.format(douyin_id))            device.type(douyin_id.encode('UTF-8'))            # 点击搜寻按钮              search_btn = vc.findViewById('com.ss.android.ugc.aweme:id/cp8')            if search_btn:                log(u'提交搜寻.')                search_btn.touch()                time.sleep(2)                vc.dump()                ## 切换到用户                  # user_tab = vc.findViewWithText(u'用户')                  # user_tab.touch()                  # 找到匹配的                  matches = []                def find_matches(view):                    if view.getClass() == 'android.widget.TextView':                        text = view.getText()                        if douyin_id.lower() in text.lower():                            # 找到匹配的了                              log(u'找到匹配的: {}'.format(text))                            matches.append(view)                        else:                            # print text                              pass                vc.traverse(transform=lambda view: find_matches(view))                if matches:                    # 有没有已关注按钮                      btn = vc.findViewWithText(u'已关注')                    if btn:                        # 先勾销关注                          log(u'之前关注过,先勾销关注.')                        btn.touch()                        time.sleep(1)                    user_matched = matches[0]                    log(u'点击进入个人主页.')                    user_matched.touch()                    time.sleep(1)                    # 点关注                      vc.dump()                    follow_btn = vc.findViewById('com.ss.android.ugc.aweme:id/aei')                    if follow_btn:                        # 点击关注                          log(u'点击关注')                        follow_btn.touch()                        time.sleep(1)                        # 点击查看更多                          vc.dump()                        viewmore_btn = vc.findViewById('com.ss.android.ugc.aweme:id/bqn')                        if viewmore_btn:                            # 点击查看更多                              log(u'点击查看更多零碎举荐')                            viewmore_btn.touch()                            time.sleep(1)                            i = 0                            while True:                                # 上滑动                                  device.drag((345, 1762), (345, 550), duration=100)                                log(u'上滑以加载更多')                                i += 1                                if i % 5 == 0:                                    # 拖动10次判断一下是否还有更多                                      vc.dump()                                    if vc.findViewWithText(u'临时没有更多了'):                                        log(u'临时没有更多了, "{}"的关注举荐数据采集结束.'.format(douyin_id))                                        # 采集胜利了                                          return True                                    failed_tip = vc.findViewWithText(u'加载失败,点击重试')                                    if failed_tip:                                        log(u'加载失败,点击重试.')                                        failed_tip.touch()                        else:                            # 没有找到查看更多按钮                              log(u'没有找到查看更多按钮')                    else:                        # 没有找到加关注按钮                          log(u'没有找到加关注按钮')                else:                    # 没有找到匹配的用户                      log(u'没有找到匹配的用户')            else:                # 没有找到搜寻提交按钮                  log(u'没有找到搜寻提交按钮.')        else:            # 没有找到搜寻输入框              log(u'没有找到搜寻输入框.')    else:        # 没有找到搜寻按钮          log(u'没有找到搜寻按钮.')

上述脚本的运行截图如下所示:

最初附上抓取到的局部示例数据:


——————————————————————————————————————————

TiToData:业余的短视频、直播数据接口服务平台。

更多信息请分割: TiToData

笼罩支流平台:抖音,快手,小红书,TikTok,YouTube

——————————————————————————————————————————

TiToData:业余的短视频、直播数据接口服务平台。

更多信息请分割: TiToData

笼罩支流平台:抖音,快手,小红书,TikTok,YouTube