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

文章目录

    • [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偏移等其他反爬技术进行综合处理。

相关推荐
思则变2 小时前
[Pytest] [Part 2]增加 log功能
开发语言·python·pytest
漫谈网络2 小时前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
try2find4 小时前
安装llama-cpp-python踩坑记
开发语言·python·llama
泡泡以安5 小时前
安卓高版本HTTPS抓包:终极解决方案
爬虫·https·安卓逆向·安卓抓包
博观而约取5 小时前
Django ORM 1. 创建模型(Model)
数据库·python·django
精灵vector6 小时前
构建专家级SQL Agent交互
python·aigc·ai编程
q567315236 小时前
Java Selenium反爬虫技术方案
java·爬虫·selenium
Zonda要好好学习6 小时前
Python入门Day2
开发语言·python
Vertira7 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
太凉7 小时前
Python之 sorted() 函数的基本语法
python