【原创】python反爬策略--字体反爬(政策网)

2023-11-01 03:30

本文主要是介绍【原创】python反爬策略--字体反爬(政策网),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

字体反爬,也是一种常见的反爬技术,这些网站采用了自定义的字体文件,在浏览器上正常显示,但是爬虫抓取下来的数据要么就是乱码,要么就是变成其他字符。下面我们通过其中一种方式解决字体反爬。

1 字体反爬案例

来源网站:查策网_https://www.chacewang.com/chanye/news。
我们可以看到网站展示的时间日期与html中的时间日期不一致,每次刷新网页,html中的时间都会变化,与实际不一致。在这里插入图片描述

2 使用环境

python3.6 + windows 10专业版 + pycharm 2019.1.3专业版

3 安装python第三方库

pip3 install requests ==2.25.1
pip3 install fontTools ==4.28.5

4 查看woff文件

刷新网页,在network中可以查看到一个woff文件,woff文件未字体加密文件,我们需要解析文件内容,得出加密字体与实际字体间的关系。
在这里插入图片描述

5 woff文件解决字体反爬全过程

5.1 调用第三方库

import requests
from fontTools.ttLib import TTFont 

5.2 请求woff链接下载woff文件到本地

# 下载woff
url = "https://web.chace-ai.com/media/fonts/fFz9g4IQsHDyEaXI.woff?version=9.666110168223948"
headers = {
'accept':'*/*',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9',
'origin':'https://www.chacewang.com',
'referer':'https://www.chacewang.com/',
'user-agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
}
resp = requests.get(url=url, headers=headers)
save_woff = 'demo.woff'
with open(save_woff, "wb") as f:f.write(resp.content)f.close()

5.3 查看woff文件内容,可以通过以下两种方式

5.3.1 通过woff文件解析器,得到结果
在这里插入图片描述
5.3.2 将woff文件转为xml文件,此操作也便于我们对字体反爬结果分析

# # woff转xml文件
font = TTFont(save_woff)
save_xml = 'demo.xml'
font.saveXML(save_xml)  # 转换为xml文件
  • 得到的xml文件如下:
    在这里插入图片描述
  • 一般来说,字体反爬是两个方式表现:
    形式一:GlyphID id与 GlyphID name形成对应关系。
    在这里插入图片描述
    形式二:通过TTGlyph name的xy坐标信息形成文字在这里插入图片描述
    在这里插入图片描述
  • 通过对比,我们发现形式一得出的结果明显不是我们想要的,因此我们对形式二进行处理。

5.4 获取所有坐标,通过matplotlib展示结果并对结果进行处理。

在这里插入图片描述
以此类推得出所有坐标的信息:
在这里插入图片描述

5.5 建立字体反爬后与原字体间对应关系

# 字体反爬坐标信息
dict_data = {'[(96, 74), (158, 38), (231, 38), (333, 38), (445, 198), (445, 346), (444, 345), (443, 346), (393, 251), (275, 251), (179, 251), (54, 382), (54, 487), (54, 599), (191, 742), (300, 742), (413, 742), (541, 565), (541, 395), (541, 185), (376, -42), (231, -42), (151, -42), (96, -16), (151, 500), (151, 423), (229, 334), (298, 334), (358, 334), (439, 415), (439, 474), (439, 555), (359, 663), (292, 663), (231, 663), (151, 570)]':'9','[(75, 98), (153, 38), (251, 38), (329, 38), (421, 115), (421, 179), (421, 323), (215, 323), (151, 323), (151, 403), (212, 403), (394, 403), (394, 538), (394, 663), (255, 663), (175, 663), (104, 609), (104, 699), (179, 742), (278, 742), (375, 742), (493, 641), (493, 560), (493, 411), (341, 369), (341, 367), (423, 358), (519, 260), (519, 186), (519, 84), (371, -42), (249, -42), (141, -42), (75, -1)]':'3','[(518, -29), (57, -29), (57, 54), (277, 274), (368, 365), (430, 472), (430, 528), (430, 593), (358, 662), (289, 662), (188, 662), (96, 576), (96, 673), (185, 742), (304, 742), (407, 742), (525, 632), (525, 538), (525, 468), (449, 332), (343, 227), (170, 58), (170, 56), (518, 56)]':'2','[(92, 88), (168, 38), (251, 38), (329, 38), (425, 125), (425, 271), (328, 351), (235, 351), (191, 351), (115, 344), (115, 730), (488, 730), (488, 645), (204, 645), (204, 430), (247, 433), (268, 433), (388, 433), (523, 311), (523, 205), (523, 94), (379, -42), (252, -42), (145, -42), (92, -10)]':'5','[(503, 632), (444, 663), (380, 663), (281, 663), (162, 491), (161, 343), (163, 343), (217, 447), (335, 447), (433, 447), (551, 319), (551, 213), (551, 101), (415, -42), (310, -42), (194, -42), (63, 139), (63, 305), (63, 506), (236, 742), (377, 742), (457, 742), (503, 720), (167, 219), (167, 144), (246, 38), (312, 38), (375, 38), (454, 130), (454, 202), (454, 281), (380, 368), (311, 368), (247, 368), (167, 280)]':'6','[(557, 168), (460, 168), (460, -29), (367, -29), (367, 168), (14, 168), (14, 230), (349, 730), (460, 730), (460, 244), (557, 244), (367, 244), (367, 562), (367, 596), (369, 640), (367, 640), (360, 621), (338, 581), (113, 244)]':'4','[(544, 696), (247, -29), (148, -29), (430, 645), (51, 645), (51, 730), (544, 730)]':'7','[(49, 335), (49, 536), (183, 742), (309, 742), (550, 742), (550, 354), (550, 162), (414, -42), (292, -42), (176, -42), (49, 151), (147, 340), (147, 38), (301, 38), (452, 38), (452, 345), (452, 663), (304, 663), (147, 663)]':'0','[(219, 370), (84, 433), (84, 553), (84, 637), (211, 742), (310, 742), (401, 742), (518, 644), (518, 565), (518, 439), (377, 371), (377, 369), (543, 309), (543, 165), (543, 70), (406, -42), (284, -42), (183, -42), (57, 69), (57, 157), (57, 302), (219, 368), (421, 554), (421, 605), (358, 664), (303, 664), (252, 664), (181, 602), (181, 555), (181, 460), (300, 410), (421, 461), (294, 325), (153, 268), (153, 162), (153, 107), (236, 37), (366, 37), (446, 107), (446, 159), (446, 269)]':'8','[(532, -29), (97, -29), (97, 54), (267, 54), (267, 630), (93, 579), (93, 668), (363, 746), (363, 54), (532, 54)]':'1',
}
# 对应实际字体信息
data_num_list = [9,3,2,5,6,4,7,0,8,1]

5.6 得到结果

在这里插入图片描述
结果一一对应,完美撒花

6 完整代码如下

# -*- coding:utf-8 _*-import os
import requests
from fontTools.ttLib import TTFont
import matplotlib.pyplot as plt
import re# 下载woff
url = "https://web.chace-ai.com/media/fonts/fFz9g4IQsHDyEaXI.woff?version=9.666110168223948"
headers = {
'accept':'*/*',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9',
'origin':'https://www.chacewang.com',
'referer':'https://www.chacewang.com/',
'user-agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
}
resp = requests.get(url=url, headers=headers)
save_woff = 'demo.woff'
with open(save_woff, "wb") as f:f.write(resp.content)f.close()
# # woff转xml文件
font = TTFont(save_woff)
save_xml = 'demo.xml'
font.saveXML(save_xml)  # 转换为xml文件# # 读取woff文件
font = TTFont('demo.woff')dict_data = {'[(96, 74), (158, 38), (231, 38), (333, 38), (445, 198), (445, 346), (444, 345), (443, 346), (393, 251), (275, 251), (179, 251), (54, 382), (54, 487), (54, 599), (191, 742), (300, 742), (413, 742), (541, 565), (541, 395), (541, 185), (376, -42), (231, -42), (151, -42), (96, -16), (151, 500), (151, 423), (229, 334), (298, 334), (358, 334), (439, 415), (439, 474), (439, 555), (359, 663), (292, 663), (231, 663), (151, 570)]':'9','[(75, 98), (153, 38), (251, 38), (329, 38), (421, 115), (421, 179), (421, 323), (215, 323), (151, 323), (151, 403), (212, 403), (394, 403), (394, 538), (394, 663), (255, 663), (175, 663), (104, 609), (104, 699), (179, 742), (278, 742), (375, 742), (493, 641), (493, 560), (493, 411), (341, 369), (341, 367), (423, 358), (519, 260), (519, 186), (519, 84), (371, -42), (249, -42), (141, -42), (75, -1)]':'3','[(518, -29), (57, -29), (57, 54), (277, 274), (368, 365), (430, 472), (430, 528), (430, 593), (358, 662), (289, 662), (188, 662), (96, 576), (96, 673), (185, 742), (304, 742), (407, 742), (525, 632), (525, 538), (525, 468), (449, 332), (343, 227), (170, 58), (170, 56), (518, 56)]':'2','[(92, 88), (168, 38), (251, 38), (329, 38), (425, 125), (425, 271), (328, 351), (235, 351), (191, 351), (115, 344), (115, 730), (488, 730), (488, 645), (204, 645), (204, 430), (247, 433), (268, 433), (388, 433), (523, 311), (523, 205), (523, 94), (379, -42), (252, -42), (145, -42), (92, -10)]':'5','[(503, 632), (444, 663), (380, 663), (281, 663), (162, 491), (161, 343), (163, 343), (217, 447), (335, 447), (433, 447), (551, 319), (551, 213), (551, 101), (415, -42), (310, -42), (194, -42), (63, 139), (63, 305), (63, 506), (236, 742), (377, 742), (457, 742), (503, 720), (167, 219), (167, 144), (246, 38), (312, 38), (375, 38), (454, 130), (454, 202), (454, 281), (380, 368), (311, 368), (247, 368), (167, 280)]':'6','[(557, 168), (460, 168), (460, -29), (367, -29), (367, 168), (14, 168), (14, 230), (349, 730), (460, 730), (460, 244), (557, 244), (367, 244), (367, 562), (367, 596), (369, 640), (367, 640), (360, 621), (338, 581), (113, 244)]':'4','[(544, 696), (247, -29), (148, -29), (430, 645), (51, 645), (51, 730), (544, 730)]':'7','[(49, 335), (49, 536), (183, 742), (309, 742), (550, 742), (550, 354), (550, 162), (414, -42), (292, -42), (176, -42), (49, 151), (147, 340), (147, 38), (301, 38), (452, 38), (452, 345), (452, 663), (304, 663), (147, 663)]':'0','[(219, 370), (84, 433), (84, 553), (84, 637), (211, 742), (310, 742), (401, 742), (518, 644), (518, 565), (518, 439), (377, 371), (377, 369), (543, 309), (543, 165), (543, 70), (406, -42), (284, -42), (183, -42), (57, 69), (57, 157), (57, 302), (219, 368), (421, 554), (421, 605), (358, 664), (303, 664), (252, 664), (181, 602), (181, 555), (181, 460), (300, 410), (421, 461), (294, 325), (153, 268), (153, 162), (153, 107), (236, 37), (366, 37), (446, 107), (446, 159), (446, 269)]':'8','[(532, -29), (97, -29), (97, 54), (267, 54), (267, 630), (93, 579), (93, 668), (363, 746), (363, 54), (532, 54)]':'1',
}
data_num_list = [9,3,2,5,6,4,7,0,8,1]result_list = []
for i in range(0,10):x = []y = []val = []for _data in font['glyf']['{}'.format(i)].coordinates:_x = _data[0]_y = _data[1]x.append(_x)y.append(_y)_val = (_x,_y)val.append(_val)_result = dict_data.get(str(val))result_list.append(_result)
# print(result_list)
_result = result_list[1:] + list(result_list[0])
print(_result)

# ps: 这是我针对此次字体反爬的解决方法,欢迎各位大佬给出意见或提问咨询

这篇关于【原创】python反爬策略--字体反爬(政策网)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/320148

相关文章

python中列表list切分的实现

《python中列表list切分的实现》列表是Python中最常用的数据结构之一,经常需要对列表进行切分操作,本文主要介绍了python中列表list切分的实现,文中通过示例代码介绍的非常详细,对大家... 目录一、列表切片的基本用法1.1 基本切片操作1.2 切片的负索引1.3 切片的省略二、列表切分的高

基于Python实现一个PDF特殊字体提取工具

《基于Python实现一个PDF特殊字体提取工具》在PDF文档处理场景中,我们常常需要针对特定格式的文本内容进行提取分析,本文介绍的PDF特殊字体提取器是一款基于Python开发的桌面应用程序感兴趣的... 目录一、应用背景与功能概述二、技术架构与核心组件2.1 技术选型2.2 系统架构三、核心功能实现解析

通过Python脚本批量复制并规范命名视频文件

《通过Python脚本批量复制并规范命名视频文件》本文介绍了如何通过Python脚本批量复制并规范命名视频文件,实现自动补齐数字编号、保留原始文件、智能识别有效文件等功能,听过代码示例介绍的非常详细,... 目录一、问题场景:杂乱的视频文件名二、完整解决方案三、关键技术解析1. 智能路径处理2. 精准文件名

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

Python使用PIL库将PNG图片转换为ICO图标的示例代码

《Python使用PIL库将PNG图片转换为ICO图标的示例代码》在软件开发和网站设计中,ICO图标是一种常用的图像格式,特别适用于应用程序图标、网页收藏夹图标等场景,本文将介绍如何使用Python的... 目录引言准备工作代码解析实践操作结果展示结语引言在软件开发和网站设计中,ICO图标是一种常用的图像

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

使用Python实现表格字段智能去重

《使用Python实现表格字段智能去重》在数据分析和处理过程中,数据清洗是一个至关重要的步骤,其中字段去重是一个常见且关键的任务,下面我们看看如何使用Python进行表格字段智能去重吧... 目录一、引言二、数据重复问题的常见场景与影响三、python在数据清洗中的优势四、基于Python的表格字段智能去重

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Python如何快速下载依赖

《Python如何快速下载依赖》本文介绍了四种在Python中快速下载依赖的方法,包括使用国内镜像源、开启pip并发下载功能、使用pipreqs批量下载项目依赖以及使用conda管理依赖,通过这些方法... 目录python快速下载依赖1. 使用国内镜像源临时使用镜像源永久配置镜像源2. 使用 pip 的并

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常