爬虫反爬:字体反爬案例分析与爬取实战

文章目录

    • [1. 字体反爬机制概述](#1. 字体反爬机制概述)
    • [2. 字体反爬原理分析](#2. 字体反爬原理分析)
      • [2.1 字体反爬的基本原理](#2.1 字体反爬的基本原理)
      • [2.2 常见字体反爬类型](#2.2 常见字体反爬类型)
    • [3. 案例分析](#3. 案例分析)
    • [4. 反反爬策略](#4. 反反爬策略)
    • [5. 实战样例](#5. 实战样例)
      • [5.1 案例1:使用Python和fontTools库破解字体反爬](#5.1 案例1:使用Python和fontTools库破解字体反爬)
      • [5.2 案例2:新闻网站字体反爬处理](#5.2 案例2:新闻网站字体反爬处理)
    • [6. 总结](#6. 总结)

1. 字体反爬机制概述

字体反爬是一种常见的反爬虫技术,通过自定义字体文件(如TTF、WOFF)对网页中的字符进行加密或替换,将页面上的文字使用特殊字体显示,而爬虫在解析时由于缺少相应的字体文件,导致无法正确识别文字内容。本文将深入分析字体反爬的机制,并提供实战样例,帮助读者理解和应对这一挑战。

2. 字体反爬原理分析

2.1 字体反爬的基本原理

字体反爬通常通过以下步骤实现:

  • 自定义字体文件:网站使用自定义的字体文件(如WOFF、TTF等),将页面上的文字映射到该字体文件中的特定字符。
  • 字符映射:在CSS中,通过@font-face规则引入自定义字体,并将页面文字应用该字体。
  • 混淆显示:实际页面上显示的文字可能是经过映射后的字符,而真实内容通过字体文件进行解码。

由于爬虫在抓取页面时,通常不会下载和应用自定义字体文件,导致解析出的文字内容为乱码或替代字符。

2.2 常见字体反爬类型

  • 图标字体:使用图标字体库(如Font Awesome)混淆文字。
  • 动态字体:通过JavaScript动态加载字体文件,增加解析难度。
  • ​​字符替换:将关键文字替换为相似的替代字符,需依赖字体文件解码。爬虫获取的是乱码或错误字符

3. 案例分析

假设有一个网页,其HTML结构如下:

html 复制代码
复制
<div class="content">
  <span class="char"></span>
  <span class="char"></span>
  <span class="char"></span>
  <span class="char"></span>
</div>

在这个例子中,网页使用了自定义字体文件,字符、等被映射到特定的字形。爬虫直接获取的文本内容是乱码,无法直接解析。

4. 反反爬策略

为了应对字体反爬,除了上述方法外,还可以采取以下策略:

  • ​自动下载与解析字体:编写脚本自动检测并下载页面使用的字体文件,使用工具(如fontTools)解析字符映射关系。
  • 模拟浏览器行为:使用无头浏览器(如Selenium、Playwright)模拟真实用户访问,确保获取渲染后的正确内容。
  • 定期更新解析规则:网站可能会更换字体文件或映射规则,需定期检查和更新爬虫的解析逻辑。
  • 结合多种数据源:通过多个渠道获取数据,交叉验证抓取结果的准确性。

5. 实战样例

以下是一个使用Python和fontTools库破解字体反爬的样例:

5.1 案例1:使用Python和fontTools库破解字体反爬

bash 复制代码
pip install requests fonttools

代码实现

python 复制代码
import requests
from fontTools.ttLib import TTFont
from bs4 import BeautifulSoup

# 目标网页URL
url = 'https://example.com'

# 获取网页内容
response = requests.get(url)
html_content = response.text

# 解析HTML
soup = BeautifulSoup(html_content, 'html.parser')

# 提取字体文件URL(假设字体文件URL在CSS中)
css_url = 'https://example.com/styles.css'
css_response = requests.get(css_url)
css_content = css_response.text

# 从CSS中提取字体文件URL(假设字体文件URL格式为'url(/path/to/font.woff)')
import re
font_url = re.search(r'url\((.*?\.woff)\)', css_content).group(1)
font_url = 'https://example.com' + font_url if font_url.startswith('/') else font_url

# 下载字体文件
font_response = requests.get(font_url)
with open('font.woff', 'wb') as f:
    f.write(font_response.content)

# 解析字体文件
font = TTFont('font.woff')
cmap = font.getBestCmap()

# 创建字符映射表
char_map = {}
for code, name in cmap.items():
    char_map[chr(code)] = name

# 示例:假设字形名称与真实字符的映射关系如下
glyph_to_char = {
    'glyph00001': 'A',
    'glyph00002': 'B',
    'glyph00003': 'C',
    'glyph00004': 'D',
}

# 替换网页中的乱码字符
content_div = soup.find('div', class_='content')
for char_span in content_div.find_all('span', class_='char'):
    char_code = char_span.text.strip()
    glyph_name = char_map.get(char_code, '')
    real_char = glyph_to_char.get(glyph_name, '?')
    char_span.string.replace_with(real_char)

# 输出解析后的文本内容
print(content_div.get_text())

5.2 案例2:新闻网站字体反爬处理

1、案例背景

假设有一个新闻网站,为了防止数据被爬取,采用了字体反爬技术。页面上的新闻标题和内容使用了自定义字体,直接抓取后显示为乱码。我们的目标是正确抓取并解析这些文字内容。

2、分析网页结构

使用浏览器的开发者工具分析页面,找到使用自定义字体的元素,并确定字体文件的URL。例如,假设字体文件通过@font-face规则引入,URL为https://example.com/fonts/custom.woff。

3、下载字体文件

使用requests库下载字体文件:

python 复制代码
import requests

font_url = 'https://example.com/fonts/custom.woff'
font_response = requests.get(font_url)
with open('custom.woff', 'wb') as f:
    f.write(font_response.content)

4、解析字体文件

使用fontTools解析字体文件,获取字符映射关系:

python 复制代码
from fontTools.ttLib import TTFont

font = TTFont('custom.woff')
cmap = font.getBestCmap()
# 将映射关系保存为字典
char_map = {hex(k): chr(v) for k, v in cmap.items()}
print(char_map)

5、抓取并解析页面内容

使用requests抓取页面HTML,使用lxml解析,并根据字符映射关系替换文字:

python 复制代码
from lxml import etree

# 抓取页面
page_url = 'https://example.com/news'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
response = requests.get(page_url, headers=headers)
html = response.text

# 解析HTML
tree = etree.HTML(html)
titles = tree.xpath('//h2[@class="news-title"]/text()')

# 替换文字
decoded_titles = []
for title in titles:
    decoded = ''.join([char_map.get(hex(ord(c))[2:], c) for c in title])
    decoded_titles.append(decoded)

for idx, title in enumerate(decoded_titles):
    print(f'新闻标题 {idx+1}: {title}')

6、处理动态加载字体

有些网站通过JavaScript动态加载字体文件,可能需要使用Selenium等工具模拟浏览器行为,获取渲染后的页面内容和字体文件URL。

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
import time

# 配置Chrome选项
chrome_options = Options()
chrome_options.add_argument("--headless")
service = Service('/path/to/chromedriver')
driver = webdriver.Chrome(service=service, options=chrome_options)

# 抓取页面
driver.get(page_url)
time.sleep(3)  # 等待字体加载

# 获取页面源代码
html = driver.page_source
driver.quit()

# 后续解析步骤同上

6. 总结

字体反爬技术通过自定义字体文件对字符进行加密或替换,增加了爬虫解析的难度。通过下载并解析字体文件,建立字符映射关系,可以有效破解这种反爬机制。在实际应用中,可能需要结合动态加载、CSS偏移等其他反爬技术进行综合处理。

相关推荐
XMYX-029 分钟前
用Python3脚本实现Excel数据到TXT文件的智能转换:自动化办公新姿势
python·自动化·excel
蹦蹦跳跳真可爱58934 分钟前
Python----数据分析(Numpy一:numpy库简介,与list列表的区别,数组的创建,随机数组的创建)
python·数据分析·numpy
微凉的衣柜35 分钟前
利用 Open3D 保存并载入相机视角的简单示例
python·open3d·点云处理
code_talking1 小时前
Python学习第十七天之PyTorch保姆级安装
人工智能·pytorch·python·conda
微刻时光1 小时前
影刀RPA + AI大语言模型:打造智能自动化流程的超级引擎
人工智能·python·语言模型·rpa·影刀rpa·影刀证书·影刀实战
凌小添1 小时前
Python入门教程丨3.5 正则表达式
python·mysql·正则表达式
鸡鸭扣2 小时前
数据结构与算法:动态规划dp:买卖股票相关力扣题(下):309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费
数据结构·python·算法·leetcode·动态规划·力扣·dp
coco_1998_22 小时前
【Win10】Anaconda + Pycharm 环境搭建教程
ide·python·pycharm
m0_748038562 小时前
NLP09-加强1-对比SVM
人工智能·python·机器学习·支持向量机·分类·nlp