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

fangdown

我的网站开发技术经验总结
首页
  • 认识ESM
  • chrome-talend插件,类似postman
  • sequelize 使用及技巧
  • UML工具Power Designer建表
  • sequelize相关操作文档
  • 解决抖音获取签名及并发的问题
  • 记一次解决抖音分享页混淆字体,字体图标转UID解决方案
    • 概况
    • 分析
    • 解决
      • 坑位: 替换不了
      • 原生https获取
      • 利用puppeteer 的response.text()方法获取
    • 总结
    • 完整代码
    • 参考
  • 获取抖音用户作品列表信息
  • 获取抖音用户作品列表信息-进阶
  • 获取抖音用户作品列表信息-进阶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-12-17
目录

记一次解决抖音分享页混淆字体,字体图标转UID解决方案

# 概况

目的: 希望通过在用户的分享页拿到用户的抖音号及相关信息

# 分析

通过chrome查看页面元素,发现大部分的阿拉伯数字都是一个,这样就无法通过获取元素的方式去得到里面的值了。

  1. 分析应该是做了处理, 所以无法查看, 百度查询一下, 确实可以看到一部分相关文章的解说,找到原因
  2. 大概原理就是 使用字体替代了数字的展现,也有相应的解决方法, 不过都是python格式的,没看到有js解析的
  3. 解决的思路就是:找到数字与字体字符串的匹配关系,把相应的字体字符串替换成数字

# 解决

  1. 找到匹配表
export const fontCodes:{[key: string]:any} = {
  "": "0", "": "0", "": "0",
  "": "1", "": "1", "": "1",
  "": "2", "": "2", "": "2",
  "": "3", "": "3", "": "3",
  "": "4", "": "4", "": "4",
  "": "5", "": "5", "": "5",
  "": "6", "": "6", "": "6",
  "": "7", "": "7", "": "7",
  "": "8", "": "8", "": "8",
  "": "9", "": "9", "": "9"
}
  1. 获取定位元素html

提示

这里花费了较多的功夫, 主要原因在于工具获取到的html元素并不是想要的原始数据

我采用的是puppeteer 工具来解析, 因为短链接会重定向到另外一个网站, 后者才是真正要的

# 坑位: 替换不了

const shortidHtml  = await page.$eval('.shortid', (el: any) => el.innerHTML)
let shortid = shortidHtml.replace('抖音ID:     ', '').replace(/<i class="icon iconfont ">/g, '').replace(/<\/i>/g, '').replace(/\s/g, '')
for (let k in fontCodes) {
  const reg = new RegExp(`${k}`, 'g')
  shortid = shortid.replace(reg, fontCodes[k])
}
// 得到undefined,打印shortidHtml发现这个拿到的结果还是
// "抖音ID:     <i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i><i class="icon iconfont ">  </i>   "
  • 解法,这里应该是puppeteer模拟了浏览器的行为,从浏览器里得到这样的数据是已经被解码过的, 应该从原始数据去拿

# 原生https获取

export const loadHtml = async (url: string): Promise<any> => {
  return new Promise(resolve => {
    var https = require('https');
    // 参数url 和 回调函数
    https.get(url, function (res: any) {
      var html = '';
      // 绑定data事件 回调函数 累加html片段
      res.on('data', function (data: any) {
        html += data;
      });
      res.on('end', function () {
        resolve(html)
      });
    }).on('error', function () {
      console.log('获取数据错误');
    });
  })
}

# 利用puppeteer 的response.text()方法获取

page.on('response', async (response: any) => {
    if (response.url().indexOf('https://www.iesdouyin.com/share/user/') > -1) {
      const content = await response.text()
      const reg = /<p class="shortid">(.*)   <\/p>/
      let shortid = ''
      if (reg.test(content)) {
        shortid = RegExp.$1
        shortid = shortid.replace('抖音ID:     ', '').replace(/<i class="icon iconfont ">/g, '').replace(/<\/i>/g, '').replace(/\s/g, '')
        for (let k in fontCodes) {
          const reg = new RegExp(`${k}`, 'g')
          shortid = shortid.replace(reg, fontCodes[k])
        }
      }
      obj.shortid = shortid
    }
  })
  // shortid 抖音ID:     JOJO<i class="icon iconfont "> &#xe617; </i><i class="icon iconfont "> &#xe617; </i><i class="icon iconfont "> &#xe61f; </i><i class="icon iconfont "> &#xe61e; </i><i class="icon iconfont "> &#xe61a; </i>
  1. 获取相应的数据
const nickname = await page.$eval('.nickname', (el: any) => el.innerText)
const uid = await page.evaluate(`document.querySelector('.focus-btn ').attributes[1].value`)
const avatar = await page.evaluate(`document.querySelector('.avatar').src`)

# 总结

本次抓取数据的难点在于要获取的原始html数据, 再根据匹配关系替换相应的字体代码, 得到想要的数字 利用的技术: 正则+ puppeteer相关api

# 完整代码

// url 短链接
const userInfoByShortUrl = async (url: string) => {
  let obj: IuserInfo = {
    uid: '',
    shortid: '',
    uniqueid: '',
    nickname: '',
    avatar: ''
  }
  const browser = await puppeteer.launch({
    // headless: false,
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
  });
  const page = await browser.newPage();
  page.on('response', async (response: any) => {
    if (response.url().indexOf('https://www.iesdouyin.com/share/user/') > -1) {
      const content = await response.text()
      const reg = /<p class="shortid">(.*)   <\/p>/
      let shortid = ''
      if (reg.test(content)) {
        shortid = RegExp.$1
        console.log('shortid', shortid)
        shortid = shortid.replace('抖音ID:     ', '').replace(/<i class="icon iconfont ">/g, '').replace(/<\/i>/g, '').replace(/\s/g, '')
        for (let k in fontCodes) {
          const reg = new RegExp(`${k}`, 'g')
          shortid = shortid.replace(reg, fontCodes[k])
        }
      }
      obj.shortid = shortid
    }
  })
  await page.emulate(iPhoneDevice);
  // 进入页面
  await page.goto(url);
  await sleep(200);
  const nickname = await page.$eval('.nickname', (el: any) => el.innerText)
  const uid = await page.evaluate(`document.querySelector('.focus-btn ').attributes[1].value`)
  const avatar = await page.evaluate(`document.querySelector('.avatar').src`)
  obj.nickname = nickname
  obj.uid = uid
  obj.uniqueid = uid
  obj.avatar = avatar
  await browser.close()
  return obj

}

# 参考

  1. 破解字体反爬(抖音爬虫) (opens new window)
  2. 抖音短视频爬取实战 (opens new window)
  3. 突破抖音反爬虫机制,字体图标替换实现通过抖音UID获取真实抖音号 (opens new window)
#抖音
上次更新: 2021/12/19, 18:05:42
解决抖音获取签名及并发的问题
获取抖音用户作品列表信息

← 解决抖音获取签名及并发的问题 获取抖音用户作品列表信息→

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