字体反爬的解决方案——突破抖音反爬虫机制

无限循环
• 阅读 7610
字体反爬案例

爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用 python 爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码。这种一般是网站设置了字体反爬。

1. 准备url

网址: https://www.iesdouyin.com/sha...

2. 获取数据 分析字体加密方式

任务:爬取个人信息展示页中的关注、粉丝人数和点赞数据,页面内容如图 下 所示。

字体反爬的解决方案——突破抖音反爬虫机制

在编写代码之前,我们需要确定目标数据的元素定位。定位时,我们在 HTML 中发现了一些奇怪的符号,HTML 代码如下:

字体反爬的解决方案——突破抖音反爬虫机制

页面中重要的数据都是一些奇怪的字符,本应该显示数字的地方在 HTML 中显示的是""。

要注意的是,Chrome 开发者工具的元素面板中显示的内容不一定是相应正文的原文,要想知道 "" 符号是什么,还需要到网页源代码中确认。对应的网页源代码如下:

</span><span class="follower block">  <span class="num">        <i class="icon iconfont follow-num"> &#xe61b; </i>    <i class="icon iconfont follow-num"> &#xe617; </i>    <i class="icon iconfont follow-num"> &#xe61a; </i>    <i class="icon iconfont follow-num"> &#xe61e; </i>.    <i class="icon iconfont follow-num"> &#xe619; </i>w   </span>  <span class="text">粉丝</span> </span>

抖音将这些数字的数据都做了字体进行映射,用了他们自己的字体,那我们可以看看开发者工具的 network 查看他所用的字体,一般都是 wolf 或者 ttf 结尾的,可以看到:

字体反爬的解决方案——突破抖音反爬虫机制

我们多刷新几次,发现一直访问的是这个字体文件:

https://s3.pstatp.com/ies/res..._falcon/static/font/iconfont_9eb9a50.woff

我们先把这个文件下载下来,font creator软件打开,看到这个图片我们就明白了字体与数字的关系

字体反爬的解决方案——突破抖音反爬虫机制

这个时候,需要大家安装pip install fontTools,使用fontTool打开ttf文件转化成xml文件

采用以下代码

from fontTools.ttLib import TTFontfont_1 = TTFont('douyin.ttf')font_1.saveXML('font_1.xml')

字体反爬的解决方案——突破抖音反爬虫机制

这个就是我们需要找的映射,配合上面在 字体和数字的对应,一起用,这个就破解了。

3. 代码实现字体映射关系

关系映射表

regex_list = [        
{'name': ['0xe602', '0xe60e', '0xe618'], 'value': '1'},        
{'name': ['0xe603', '0xe60d', '0xe616'], 'value': '0'},        
{'name': ['0xe604', '0xe611', '0xe61a'], 'value': '3'},        
{'name': ['0xe605', '0xe610', '0xe617'], 'value': '2'},        
{'name': ['0xe606', '0xe60c', '0xe619'], 'value': '4'},        
{'name': ['0xe607', '0xe60f', '0xe61b'], 'value': '5'},        
{'name': ['0xe608', '0xe612', '0xe61f'], 'value': '6'},        
{'name': ['0xe609', '0xe615', '0xe61e'], 'value': '9'},        
{'name': ['0xe60a', '0xe613', '0xe61c'], 'value': '7'},        
{'name': ['0xe60b', '0xe614', '0xe61d'], 'value': '8'}    ]

4. 完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import requests
from lxml import etree

start_url = ' https://www.iesdouyin.com/share/user/88445518961'


def get_real_num(content):
    content = content.replace(' &#', '0').replace('; ', '')
    regex_list = [
        {'name': ['0xe602', '0xe60e', '0xe618'], 'value': '1'},
        {'name': ['0xe603', '0xe60d', '0xe616'], 'value': '0'},
        {'name': ['0xe604', '0xe611', '0xe61a'], 'value': '3'},
        {'name': ['0xe605', '0xe610', '0xe617'], 'value': '2'},
        {'name': ['0xe606', '0xe60c', '0xe619'], 'value': '4'},
        {'name': ['0xe607', '0xe60f', '0xe61b'], 'value': '5'},
        {'name': ['0xe608', '0xe612', '0xe61f'], 'value': '6'},
        {'name': ['0xe609', '0xe615', '0xe61e'], 'value': '9'},
        {'name': ['0xe60a', '0xe613', '0xe61c'], 'value': '7'},
        {'name': ['0xe60b', '0xe614', '0xe61d'], 'value': '8'}
    ]

    for i1 in regex_list:
        for font_code in i1['name']:
            content = re.sub(font_code, str(i1['value']), content)

    html = etree.HTML(content)
    douyin_info = {}
    # 获取抖音ID
    douyin_id = ''.join(html.xpath("//div[@class='personal-card']/div[@class='info1']/p[@class='shortid']/text()"))
    douyin_id = douyin_id.replace('抖音ID:', '').replace(' ', '')
    i_id = ''.join(html.xpath("//div[@class='personal-card']/div[@class='info1']/p[@class='shortid']/i/text()"))
    douyin_info['douyin_id'] = str(douyin_id) + str(i_id)

    # 关注
    douyin_info['follow_count'] = ''.join(html.xpath(
        "//div[@class='personal-card']/div[@class='info2']/p[@class='follow-info']//span[@class='focus block']//i/text()"))
    # 粉丝
    fans_value = ''.join(html.xpath(
        "//div[@class='personal-card']/div[@class='info2']/p[@class='follow-info']//span[@class='follower block']//i[@class='icon iconfont follow-num']/text()"))

    unit = html.xpath(
        "//div[@class='personal-card']/div[@class='info2']/p[@class='follow-info']//span[@class='follower block']/span[@class='num']/text()")
    if unit[-1].strip() == 'w':
        douyin_info['fans'] = str(float(fans_value) / 10) + 'w'
        fans_count = douyin_info['fans'][:-1]
        fans_count = float(fans_count)
        fans_count = fans_count * 10000
        douyin_info['fans_count'] = fans_count
    else:
        douyin_info['fans'] = fans_value
        douyin_info['fans_count'] = fans_value
    # 点赞
    like = ''.join(html.xpath(
        "//div[@class='personal-card']/div[@class='info2']/p[@class='follow-info']//span[@class='liked-num block']//i[@class='icon iconfont follow-num']/text()"))
    unit = html.xpath(
        "//div[@class='personal-card']/div[@class='info2']/p[@class='follow-info']//span[@class='liked-num block']/span[@class='num']/text()")
    if unit[-1].strip() == 'w':
        douyin_info['like'] = str(float(like) / 10) + 'w'
        like_count = douyin_info['like'][:-1]
        like_count = float(like_count)
        like_count = like_count * 10000
        douyin_info['like_count'] = like_count
    else:
        douyin_info['like'] = like
        douyin_info['like_count'] = like

    # 作品
    worko_count = ''.join(html.xpath("//div[@class='video-tab']/div/div[1]//i/text()"))
    douyin_info['work_count'] = worko_count
    return douyin_info


def get_html():
    header = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'
    }
    response = requests.get(url=start_url, headers=header, verify=False)
    return response.text


def run():
    content = get_html()
    info = get_real_num(content)
    print(info)

if __name__ == '__main__':
    run()


5. 结果

字体反爬的解决方案——突破抖音反爬虫机制

点赞
收藏
评论区
推荐文章
菜鸟阿都 菜鸟阿都
4年前
创建免费ip代理池
&ensp;&ensp;&ensp;&ensp; 反爬技术越来越成熟,为了爬取目标数据,必须对爬虫的请求进行伪装,骗过目标系统,目标系统通过判断请求的访问频次或请求参数将疑似爬虫的ip进行封禁,要求进行安全验证,通过python的第三方库faker可以随机生成header伪装请求头,并且减缓爬虫的爬取速度,能很好的避过多数目标系统的反扒机制,但对一些安全等级
Wesley13 Wesley13
3年前
java爬虫进阶 —— ip池使用,iframe嵌套,异步访问破解
写之前稍微说一下我对爬与反爬关系的理解一、什么是爬虫   爬虫英文是splider,也就是蜘蛛的意思,web网络爬虫系统的功能是下载网页数据,进行所需数据的采集。主体也就是根据开始的超链接,下载解析目标页面,这时有两件事,一是把相关超链接继续往容器内添加,二是解析页面目标数据,不断循环,直到没有url解析为止。举个栗子:我现在要爬取苏宁手机价
把帆帆喂饱 把帆帆喂饱
4年前
爬虫
爬虫什么是爬虫使用编程语言所编写的一个用于爬取web或app数据的应用程序怎么爬取数据1.找到要爬取的目标网站、发起请求2.分析URL是如何变化的和提取有用的URL3.提取有用的数据爬虫数据能随便爬取吗?遵守robots.txt协议爬虫的分类通用网络爬虫百度,Google等搜索引擎,从一些初识的URL扩展到整个网站,主要为门户站点搜索引擎和大型网站服务采
Stella981 Stella981
3年前
Nginx反爬虫: 禁止某些User Agent抓取网站
一、概述网站反爬虫的原因不遵守规范的爬虫会影响网站的正常使用网站上的数据是公司的重要资产爬虫对网站的爬取会造成网站统计数据的污染常见反爬虫手段1\.根据IP访问频率封禁IP2\.设置账号登陆时长,账号访问过多封禁设置账号的登录限制,只有登录才能展现内容
Stella981 Stella981
3年前
Python爬虫实例:爬取猫眼电影——破解字体反爬
 字体反爬字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的。现在貌似不少网站都有采用这种反爬机制,我们通过猫眼的实际情况来解释一下。下图的是猫眼网页上的显示:!(https://oscimg.oschina.
如何应对亚马逊反爬机制
大家都知道亚马逊是全球最大的购物平台很多商品信息、用户评价等等都是最丰富的。但是对于爬虫来说,亚马逊的反爬机制应该也是数一数二的,想要获取亚马逊数据的人很多,但是真的能成功的确是少数,所以今天小编就手把手带大家,越过亚马逊的各种反爬机制爬取你想要的商品、评论等等有用信息。这里我们可以通过以下一些步骤去实现亚马逊数据的获取。一、使用requests的get请求
网站反爬之封IP应对措施
作为爬虫工作者爬取数据是基本的技能,在日常获取数据的过程中遇到网站反爬也是家常事,网站的反爬方式有很多,今天我们重点来分析下封IP的行为。这种情况下大家都是很简单的使用代理IP就解决了,但是网上ip代理有很多家,到底选哪家好呢?这里推荐口碑很好的亿牛云
python爬取数据中的headers和代理IP问题
爬虫的主要爬取方式之一是聚焦爬虫,也就是说,爬取某一个特定网站或者具有特定内容的网站,而一般比较大的有价值的网站都会有反爬策略,其中常见的反爬策略是网站根据来访者的身份判定是否予以放行。对来访者身份的判定一般基于headers里的userAgent值,每一
小白学大数据 小白学大数据
2个月前
如何通过requests和time模块限制爬虫请求速率?
一、为什么需要限制爬虫请求速率?在爬取网站数据时,网站服务器需要处理我们的请求并返回数据。如果爬虫的请求过于频繁,服务器可能会因为负载过高而崩溃,或者将我们的爬虫IP地址封禁。此外,许多网站都有反爬虫机制,例如检测单位时间内来自同一IP的请求频率。如果请求
无限循环
无限循环
Lv1
十年旧梦无寻处,几度新春不在家。
文章
2
粉丝
0
获赞
0