当前位置: 首页 > article >正文

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

文章目录

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

1. 字体反爬机制概述

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

2. 字体反爬原理分析

2.1 字体反爬的基本原理

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

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

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

2.2 常见字体反爬类型

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

3. 案例分析

假设有一个网页,其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库破解字体反爬

pip install requests fonttools

代码实现

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库下载字体文件:

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解析字体文件,获取字符映射关系:

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解析,并根据字符映射关系替换文字:

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。

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


http://www.kler.cn/a/563334.html

相关文章:

  • 记一次线上Tomcat服务内存溢出的问题处理
  • JVM生产环境问题定位与解决实战(二):JConsole、VisualVM到MAT的高级应用
  • 什么是完全前向保密(PFS)?
  • muduo网络库2
  • HTTP 动态报错码的原因和解决方法
  • 力扣——完全平方数
  • ChatGPT入驻Safari,AI搜索时代加速到来
  • 安科瑞DJSF1352直流电能表在光伏串组箱的应用:提升光伏发电效率与安全的智能利器-安科瑞 耿笠
  • 【JavaEE进阶】MyBatis 操作数据库(1)
  • Mysql疑难报错排查 - Field ‘XXX‘ doesn‘t have a default value
  • MySQL--索引的优化--LIKE模糊查询
  • Java IO 和 NIO 的基本概念和 API
  • 渗透测试(WAF过滤information_schema库的绕过,sqllib-46关,海洋cms9版本的注入)
  • SOME/IP-SD -- 协议英文原文讲解4
  • 【leetcode hot 100 11】移动零
  • FTP出现“打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。”如何处理?
  • SpringBoot 2 后端通用开发模板搭建(异常处理,请求响应)
  • DeepSeek “源神”启动!「GitHub 热点速览」
  • Harbor服务需要crt证书,而下载是nginx的证书pem,应该怎么处理
  • uniapp-X 对象动态取值