利用fonttools破解网页字体加密反爬

import re
import time
import requests
from lxml import etree
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from fontTools.ttLib import TTFont  #导入字体处理模块

# 定义请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
# 实例化options对象
options = Options()
# 添加experimental_option,禁用自动化扩展,防止被检测到使用了自动化工具进行操作
options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 添加argument, 禁用浏览器自动化特性,防止被检测到使用了自动化工具进行操作
options.add_argument("--disable-blink-features=AutomationControlled")
# 添加argument,忽略证书错误,防止因证书错误导致的访问失败
options.add_argument('ignore-certificate-errors')
# 实例化浏览器对象
driver = webdriver.Chrome(options=options)
driver.get('https://www.qidian.com/rank/yuepiao/')
driver.maximize_window()
# 获取网页html数据
html_text = driver.page_source
# 使用xpath表达式筛选出20本书的名字
html = etree.HTML(html_text)
book_name_list = html.xpath('//h2/a/text()')
# 使用xpath表达式筛选出20本书的月票数
book_ticket_text_list = html.xpath('//p/span/span/text()')
# 定义空列表用于存放还原后的20本书的原始符号
book_ticket_list = []
# 将渲染后的乱码文本还原成网页中看到的原始符号
for book_ticket_text in book_ticket_text_list:
    # 将字符串中的每个字符进行还原
    converted_data = ''.join('&#{};'.format(ord(b)) for b in book_ticket_text)
    # 将还原的每本书的月票原始字符追加到列表中
    book_ticket_list.append(converted_data)

# 从网页中筛选出字体链接所在的style标签
font_url_text = html.xpath('//style/text()')[0]

"""
format('eot'); src: url('https://qidian.gtimg.com/qd_anti_spider/qqIQdXrX.woff') format('woff')
"""
# 使用正则表达式来筛选出字体文件的链接
font_re = r"format\('eot'\); src: url\('(.*?)'\) format\('woff'\)"
font_url = re.findall(font_re, font_url_text)[0]
# 发起网络请求获取字体文件的数据
response = requests.get(font_url, headers=headers)
# 将字体数据保存成字体文件
with open('font.woff', 'wb') as file:
    file.write(response.content)
# 使用TTFont打开字体文件
font_obj = TTFont('font.woff')
# 从字体文件中提取cmap数据
cmap_dict = font_obj.getBestCmap()
# 定义英文与数字的对应字典
number_dict = {
    'one': '1',
    'two': '2',
    'three': '3',
    'four': '4',
    'five': '5',
    'six': '6',
    'seven': '7',
    'eight': '8',
    'nine': '9',
    'zero': '0',
    'period': '.',
}
# 将读取出来的cmap数据中的英文单词替换成阿拉伯数字
for i in cmap_dict:
    for j in number_dict:
        if cmap_dict[i] == j:
            cmap_dict[i] = number_dict[j]

for book_name, book_ticket in zip(book_name_list, book_ticket_list):
    # 将原始字符中的&#;这三个符号去除
    number_list = re.findall(r'\d+', book_ticket)
    # 定义一个空字符产用于保存每本书的中月票的每位数
    number_str = ''
    # 对去除后的原始字符列表进行遍历,得到每位数的十进制值
    for number in number_list:
        # 从替换后的cmap字典中使用遍历出来的键去取值
        num = cmap_dict.get(int(number))
        # 将取出来的每位数连接起来
        number_str += num
    print(f'书籍名称:{book_name}  月票数量:{number_str}')

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值