我的网站开发技术经验总结 我的网站开发技术经验总结
首页

fangdown

我的网站开发技术经验总结
首页
  • 认识ESM
  • chrome-talend插件,类似postman
  • sequelize 使用及技巧
  • UML工具Power Designer建表
  • sequelize相关操作文档
  • 解决抖音获取签名及并发的问题
  • 记一次解决抖音分享页混淆字体,字体图标转UID解决方案
  • 获取抖音用户作品列表信息
    • 需求
    • 分析
    • 实践
      • 抖音app抓包
    • 总结:
    • 相关
    • 附上代码
  • 获取抖音用户作品列表信息-进阶
  • 获取抖音用户作品列表信息-进阶3
  • 如何根据抖音号获取用户信息
  • 获取用户最新视频
  • 模块化-import和require的区别
  • eslint规范
  • js容错处理
  • js-数组分组,执行promise
  • reduce使用遇到的问题
  • 正则匹配html的元素内容
  • taro 小程序 弹窗层禁止底部滚动
  • 公众号签名问题
  • CentOS7中MariaDB重置密码
  • nginx多域名配置
  • node访问接口,得到乱码的结果,原因-Accept-Encoding
  • node写文件到json中
  • node抓取html内容
  • Node.js使用ES6语法
  • express 使用cors中间件解决跨域
  • node + express + session + redis 进行持久化缓存
  • node中读取文件夹,获取文件名称
  • pm2常用命令
  • 使用pm2管理后台node服务
  • typescript puppeteer支持window及document属性
  • node读取json文件
  • node中使用redis缓存
  • node + github的webhook完成自动部署
  • vuepress-blog的性能优化-CDN
  • CENTOS7下安装REDIS
  • promise then和catch的学习和使用
  • promise在循环中的串行并行用法
  • puppeteer常用知识
  • centos部署安装puppeteer
  • python的学习和使用
  • Taro+TypeScript - Mobx实践
  • 爬虫系列 --- 反爬机制和破解方法汇总
  • 安全-html转码
  • taro中使用animation动画
  • charles 使用
  • Mac下VSCode设置iTerm2终端样式
  • centos一步步完成站点部署
  • 云闪付做地铁的思路
  • 准备技能
  • 备案pc项目介绍
  • 备案小程序项目介绍
  • 小程序二维码扫码功能
  • 小程序域名组件开发
  • 小程序添加水印
  • 规则引擎优化
  • 记一次hooks代替redux的经历
  • 通过nodejs+koa+stream进行服务端图片代理
  • nodeJs接入log4j日志
  • nodejs+typescript项目中添加全局global属性
  • create-react-app 安装 bizcharts 项目崩溃
  • 使用MutationObserver监控dom的变化
  • 服务器重启后启动相关服务
  • moment国际化的问题
  • 项目经验
fangdown
2019-11-14
目录

获取抖音用户作品列表信息

# 需求

获取指定用户的作品信息,包含标题、时间、播放地址等

# 分析

获取用户信息的方式:

  1. 星图达人

星图达人只有一小部分作品,不满足需求

  1. 哪里有列表,分析列表接口

# 实践

# 抖音app抓包

  1. 使用Charles进行抓包
https://aweme-hl.snssdk.com/aweme/v1/search/item/?iid=91648520549&aid=1128&mcc_mnc=&os_api=18&app_name=aweme&channel=App%20Store&idfa=3911688C-3A52-4237-BC0C-84255F48E141&device_platform=iphone&build_number=83101&vid=614D7CD9-AE0B-4E29-91CB-D06791916C23&openudid=bf7f9afd8bc01da17253c34849f70701a2e985a3&device_type=iPhone9,4&app_version=8.3.1&js_sdk_version=1.17.4.1&device_id=68291934124&ac=WIFI&version_code=8.3.1&os_version=10.2&screen_width=1242&source=video_search&search_id=201911071144490100260780891712893F&offset=120&query_correct_type=1&count=12&keyword=%E5%B0%8F%E4%BB%99%E7%88%B1%E7%94%9F%E6%B4%BB&hot_search=0

很容易就获取到了用户列表滚动加载的接口,设置offset和count 进行获取数据!!! 然而现实很骨感,返回的接口是空数据!! 哪里不对呢?(此时不知道抖音接口有加密) 是不是哪里设置错了呢? 进过一番折腾(网页请求、postman请求等),都不得解,最后知道抖音接口加密了,继续抓包查看请求头部header header信息

"x-tt-token":"000c2f72735ade685f370d832c3ea4d2549d057cbeb7b24350b15572702d25077074f2540c27f20a6cca49dab3b899cc6135",
"x-tt-trace-id": "00-80c302f19427f59a8e0ff4926a9cab1d-80c302f19427f59a-01",
"x-ss-dp": 1128,
"user-Agent": "Aweme 8.3.1 rv:83101 (iPhone; iOS 10.2; zh_CN) Cronet",
"x-gorgon": "830000000000a3122894b28e071f1455c00e85d18b4967ba1e67",
"x-khronos": 1573116669,
"sdk-version": 1

ok,那就把头部信息带入请求中。 结果还是得不到数据?why?一头闷逼

为什么抓包就能获取数据,而我模拟请求就获取不到数据呢?有什么差异呢,对比一下

经过对比,发现每次的请求这些请求头部的参数值不一样

x-gorgon
x-khronos

这个值是怎么来的呢? 不知道,于是百度搜索!!!

从这里才开始知道抖音接口有加密这个功能!!!

用什么算法加密,不清楚? 怎么样获取x-gorgon的值, 可以模拟动态计算吗? 不知道

经过网上的一番折腾,明白了抖音是故意这样的,就是防止接口被刷吧!

解决方式有2种:

  • 破解app,逆推算法
  • 有第三方人在卖相应的接口

难道除了以上方法就没有别的了吗?不甘心,继续github和百度、Google

爬虫很多人用了python,有的时候需要下载别人的工程去试试可不可以,于是学习python,边学边用

在诸多的信息反馈中,得知抖音有用户m站,于是打开

https://www.iesdouyin.com/share/user/99007818191

这里包含了用户作品列表、喜欢列表、粉丝量、点赞量

也是滚动加载,可以通过接口去拿,不过有了抖音App接口的经验,并没有高兴起来,先看接口长啥样 果然不出所料,有签名信息,肯定是动态的

_signature: sC0QzBAU7e5XWujK0PgnC7AtEN
dytk: 241ee964ddd0156f2efe4cdc664654bf

对比了一下不同用户的签名,发现是不一样的,那么就不能批量去获取用户信息了

怎么办!!! 难点又来了

好在这是在web端,比客户端好解决多了

放出大招!!!puppeteer

之前看过一篇文章讲述使用puppeteer进行爬虫的文章,有感而发,模拟用户行为,签名不用自己造,觉得可行,于是行动起来

在puppeteer中用到了以下技术

  • 监听requestfinished事件,获取请求返回的数据,把数据放入数组中
  • 模拟滑动屏幕,每500毫秒让页面下滑100像素的距离,获取了所有作品
  • 通过串行的方式把分id获取视频列表,并把结果写入文件

最后把代码进行整理,封装!!

# 总结:

  • 第一次碰到这么复杂的接口,抖音做的应该是很厉害了, 防刷做的很好,加密算法运用的好
  • 未知事物总是很难, 要一步步去分析找到解决方案,也许结果很简单,但是没有找到思路或方法,就像一座大山,难以迈过
  • 学会搜索,(百度+github),百度搜不了github,搜索能给人很多帮助
  • 学会交流,找一些群或者人,主动去询问难点,你的难点对于别人来说未必是难点,也许是一句话的事情
  • 相信自己可以去解决问题

# 相关

  • 获取抖音用户作品列表信息-进阶2 (opens new window)
  • 获取抖音用户作品列表信息-进阶3 (opens new window)

# 附上代码

const fs = require('fs');
const puppeteer = require('puppeteer');
const moment= require('moment')
// 获取抖音用户作品列表~
const douyinList = (id) => {
  return new Promise(async resolve => {
    const browser = await (puppeteer.launch({ headless: false }));
    const page = await browser.newPage();
    let allInfo = [];
    page.on('requestfailed', request => {
      console.log(request.url() + ' ' + request.failure().errorText);
    });
    page.on('requestfinished', request => {
      // 查看所有请求地址
      if (request.resourceType() === "xhr") {
        // 匹配所需数据的请求地址
        if(request.url().indexOf('https://www.iesdouyin.com/web/api/v2/aweme/post') !== -1) {
          const waitResult = async () => {
            try {
              // 获取数据并转为json格式
              console.log('等待请求结果')
              let res = await request.response();
              let result = await res.json();
              const awemeList = result.aweme_list
              const {min_cursor, max_cursor} = result
              const startDate = moment(min_cursor).format('YYYY-MM-DD')
              const endDate = moment(max_cursor).format('YYYY-MM-DD')

              const list = awemeList.map(item => {
                const {aweme_id, desc, video,statistics} = item
                const video_src = `https://www.iesdouyin.com/share/video/${aweme_id}/?region=CN&mid=&u_code=&titleType=title&utm_source=copy_link&utm_campaign=client_share&utm_medium=android&app=aweme`
                return {
                  aweme_id, desc, video_src,video,statistics,startDate,endDate  
                }
              })
              allInfo.push(...list)
            } catch(err){
              console.log(err)
            }
          }
          waitResult()
        }
      }
    })
    // 进入页面
    await page.goto(`https://www.iesdouyin.com/share/user/${id}`);
    const title = await page.$eval('.nickname', el => el.innerHTML);
    console.log(title);

    console.log('开始滚动到底部')
    await autoScroll(page);
    console.log(`共获取到${allInfo.length}个作品信息`);
    
    // 将作品信息写入文件
    let writerStream = fs.createWriteStream(`douyin-${id}.json`);
    writerStream.write(JSON.stringify(allInfo, undefined, 2), 'UTF8');
    writerStream.end();
    await page.waitFor(5000);
    browser.close();
    resolve()
    // 滑动屏幕,滚至页面底部
    function autoScroll(page) {
      return page.evaluate(() => {
        return new Promise((resolve) => {
          var totalHeight = 0;
          var distance = 100;
          // 每500毫秒让页面下滑100像素的距离
          var timer = setInterval(() => {
            var scrollHeight = document.body.scrollHeight;
            window.scrollBy(0, distance);
            totalHeight += distance;
            if (totalHeight >= scrollHeight) {
              clearInterval(timer);
              resolve();
            }
          }, 500);
        })
      });
    }
  })
}

const arr = ['102269017585', '58146392181']
let index = 0
const doTask = async (arr) => {
  console.log('index', index)
  await douyinList(arr[index++])
  if(index <= arr.length -1){
    doTask(arr)
    return
  }
  console.log('task is done')
}
doTask(arr)
#抖音
上次更新: 2021/12/19, 18:05:42
记一次解决抖音分享页混淆字体,字体图标转UID解决方案
获取抖音用户作品列表信息-进阶

← 记一次解决抖音分享页混淆字体,字体图标转UID解决方案 获取抖音用户作品列表信息-进阶→

最近更新
01
多分支修复撞车的问题
05-01
02
如何成为架构师
01-23
03
服务器部署全过程
11-23
更多文章>
Theme by Vdoing | Copyright © 2019-2026 fangdown | 粤ICP备19079809号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式