1. 实习那僧
实习那僧是一家线上实习招聘网站,提供各行业实习职位的查询和申请。然而,在数据爬取过程中,我们可能会遇到网站的反爬机制。接下来,我们以实习那僧为例,介绍如何使用 Python 突破网站的字体反爬机制。
2. 实现字体反爬
2.1 分析网站
在爬虫之前,我们需要了解网站的反爬机制。在对实习那僧进行网页抓取时,我们可以发现,网站中的文字存在一定的处理,具体表现为:
@font-face {
font-family: 'iconfont';
src: url('//s.icons-aliyun.com/1v0/imsa/fonts/iconfont/fmui.eot');
src: url('//s.icons-aliyun.com/1v0/imsa/fonts/iconfont/fmui.eot?#iefix') format('embedded-opentype'),
url('//s.icons-aliyun.com/1v0/imsa/fonts/iconfont/fmui.woff') format('woff'),
url('//s.icons-aliyun.com/1v0/imsa/fonts/iconfont/fmui.ttf') format('truetype'),
url('//s.icons-aliyun.com/1v0/imsa/fonts/iconfont/fmui.svg#iconfont') format('svg');
}
可见,实习那僧网站采用了字体图标的方式,将常规的文字转化为图标后再进行渲染。这种方式有效地防止了爬虫直接抓取文字信息。
2.2 使用 fonttools 库
为了解析网站中的字体文件,我们使用 Python 的 fonttools 库。fonttools 能够对字体文件进行解析,找到每个字符对应的 Unicode 码点,从而帮助我们破解字体反爬。
我们可以从实习那僧的首页中提取出其使用的字体文件,然后根据字体文件的路径下载并解码,得到一个 TTF 格式的字体文件。接着,我们可以使用 fonttools 库中的 TTFont 类来解析字体文件,找到每个字符对应的 Unicode 码点。
import base64
import requests
from fontTools.ttLib import TTFont
# 提取并解码字体文件
response = requests.get('https://s.icons-aliyun.com/1v0/imsa/fonts/iconfont/fmui.ttf')
font = TTFont(BytesIO(response.content))
font.saveXML('font.xml') # 将字体文件保存为 XML
# 解析字体文件
glyphs = font.getGlyphOrder()[1:] # 获取字符集
uni_list = font.getGlyphOrder()[1:] # 获取 Unicode 码点集
font_dict = {}
for glyph in glyphs:
glyph_str = font['glyf'][glyph].description
for uni in uni_list:
if font['glyf'][uni].description == glyph_str:
font_dict[str(glyph)] = unichr(int(uni[3:], 16))
# 字体映射表
font_dict = {'uniE068': '6', 'uniEBB3': 'b', 'uniFE91': '5', 'uniFE9A': '7', 'uniFEEA': 'a', 'uniFF14': '4', 'uni ...}
2.3 替换网页中的字符
我们已经获取到了字体文件中字符与 Unicode 码点之间的映射表。接下来,我们需要将实习那僧网站中的字符替换为 Unicode 码点,以便正常显示网页内容。
在 HTTP 请求中,我们可以设置一个 headers 参数,来修改浏览器向网站发送的请求头。由于网站中的字符采用字体图标的方式呈现,因此我们需要修改请求头,将 font-family 设为 font_dict,即可实现对网站字符的替换。值得注意的是,我们需要使用正则表达式匹配网站中的字符,以便准确地进行替换。
# 获取网页内容
response = requests.get(url, headers={
'User-Agent': ua,
'Referer': referer,
'Cookie': cookie,
'Host': host,
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'font-family': str(font_dict)})
content = response.content.decode('utf-8')
# 字符替换
content = re.sub(r'(?<=\\)u[a-zA-Z0-9]{4}', lambda x: str(ord(x.group(0)[2:])), content)
3. 总结
本文介绍了如何使用 Python 突破实习那僧网站的字体反爬机制。具体实现过程中,我们对网站中使用的字体文件进行了解析,得到了字体图标字符与 Unicode 码点之间的映射表。然后,我们使用正则表达式来识别网站中的字符,并将其替换为对应的 Unicode 码点。通过这种方式,我们成功突破了实习那僧网站的字体反爬机制,实现了对网页的正常访问。