破解起点小说网字体加密

参考博客

https://blog.csdn.net/u012082590/article/details/89024889

import requests
import re
from fontTools.ttLib import TTFont

# <span class="MZYjnXxB">&#100098;&#100098;&#100094;&#100090;&#100093;&#100094;</span></em>
url = 'https://book.qidian.com/info/1004608738'
response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'})
# print(response.text)
font_url = re.search(re.compile(r"@font-face.*?src.*?src: url\('(.*?)'\)", re.S), response.text).group(1)
# print(font_url)
data = re.search(re.compile(r'<div class="book-info ">.*?<p>.*?<em>.*?<span class=".*?">(.*?)</span>', re.S), response.text).group(1)
print(data)

num_list = []
numbers = data.split(';')
for num in numbers:
    if num:
        # %x:十六进制的占位符
        res = '%x' % int(num.replace('&#', ''))
        num_list.append(res)

print(font_url, num_list)
# 4. 请求字体文件的url,获取字体文件的内容。
font_response = requests.get(font_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}).content
with open('qd.woff', 'wb') as f:
    f.write(font_response)

# 5. 将本地保存的qd.woff转化成qd.xml文件。
f = TTFont('qd.woff')
f.saveXML('qd.xml')

# 6. 根据十六进制的列表,从xml中根据code的值获取map标签。解析xml标签结构。
# [186f1, 186f2, 186f3, 186f4, 186f5]
from xml.etree import ElementTree
# 获取xml文件的根节点(文档树对象) obj(<Element object xxx>) = etree.HTML(page_source, parse=etree.HTMLParse(encoding="utf8"))
root_obj = ElementTree.parse('qd.xml').getroot()
# 在root_obj的基础上,开始查找<map>标签。
# find()类似于selenium中的find()
# <Element 'cmap_format_12' at 0x0000000003B2F548>
maps_element = root_obj.find('cmap').find('cmap_format_12').findall('map')
# 遍历maps_element这个列表,里面保存的全部都是<Element 'map' at xxx>对象。
map_ele_dict = {}
for map_ele in maps_element:
    # 取出map标签内的code和name属性的值。
    # 以code为键,以name为值,保存到字典map_ele_dict
    map_ele_dict[map_ele.attrib['code'].replace('0x', '')] = map_ele.attrib['name']



# 7. xml解析完毕,会得到如下数据:
# a. 网页源代码数据['1883d', '1883d', '18840', '1883e', '18838', '1883c']
# b. 字体文件xml中的数据:
#{'18836': 'nine', '18838': 'six', '18839': 'two', '1883a': 'eight', '1883b': 'three', '1883c': 'five', '1883d': 'four', '1883e': 'period', '1883f': 'zero', '18840': 'one', '18841': 'seven'}
convert_dict = {
    'one': '1',
    'two': '2',
    'three': '3',
    'four': '4',
    'five': '5',
    'six': '6',
    'seven': '7',
    'eight': '8',
    'nine': '9',
    'zero': '0',
    'period': '.'
}
# 接下来,将源代码数据遍历
result = ''
for number in num_list:
    # 从字典map_ele_dict中取出对应的one, two, three...
    english_number = map_ele_dict[number]
    # 再以one, two, three...为键,从字典convert_dict中取出阿拉伯数字
    alb_number = convert_dict[english_number]
    result += alb_number

print(result)

这个代码还是比较容易得

那个对应关系可以通过一个工具查看,官方提供免费版本下载但是要邮箱激活

 

 另一方面,就是有些包需要装都是pip安装的,少啥装啥就行了。

可以打开xml文件看看

 

 我们可以看到code那对应的是十六进制的数据,怎么知道的,因为

 

 0-9 A-F 的范围是十六进制的,数据里出现了f的。。然后就是从根目录开始寻找节点,一直找到code和name,组成字典,再将处理过的页面里的数据作为键去取值,得到name,再根据那个表找对应的数据就行了。

这里最坑的就是正则匹配,

根据上面的原理去处理另一个页面的数据,整个人都不好了。。。

https://www.qidian.com/free/all?chanId=21&orderId=&vip=hidden&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=1&page=3

这个网页很神奇,用程序请求的代码少了关键部分代码,但是你看不见又可以用正则等东西从源码里把数据匹配出来,真的是没谁了,几年第一次遇到这种的。所以正则一定多注意,不是批不出来,是没写对。。
import requests
import re
from fontTools.ttLib import TTFont

headers= {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'
}
source = requests.get('https://www.qidian.com/free/all?chanId=21&orderId=&vip=hidden&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=1&page=3',headers=headers).text
print(source)
demo = re.compile('<\/style><span class=".*?">(&#.*?;)</span>万字',re.S)
lists = demo.findall(source)
print(lists)

urls = re.compile('(https:\/\/qidian\.gtimg\.com\/qd_anti_spider\/\w+\.woff)',re.S)
woff = urls.findall(source)[0]
print(woff)
font_response = requests.get(woff, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}).content
with open('qd.woff', 'wb') as f:
    f.write(font_response)

f = TTFont('qd.woff')
f.saveXML('qd.xml')



from xml.etree import ElementTree
root_obj = ElementTree.parse('qd.xml').getroot()
maps_element = root_obj.find('cmap').find('cmap_format_12').findall('map')
map_ele_dict = {}
for map_ele in maps_element:
    # 取出map标签内的code和name属性的值。
    # 以code为键,以name为值,保存到字典map_ele_dict
    map_ele_dict[map_ele.attrib['code'].replace('0x', '')] = map_ele.attrib['name']
convert_dict = {
    'one': '1',
    'two': '2',
    'three': '3',
    'four': '4',
    'five': '5',
    'six': '6',
    'seven': '7',
    'eight': '8',
    'nine': '9',
    'zero': '0',
    'period': '.'
}

for i in lists:
    num_list = []
    numbers = i.split(';')
    for num in numbers:
        if num:
            # %x:十六进制的占位符
            res = '%x' % int(num.replace('&#', ''))
            num_list.append(res)
    print(num_list)
    result = ''
    for number in num_list:
        # 从字典map_ele_dict中取出对应的one, two, three...
        english_number = map_ele_dict[number]
        # 再以one, two, three...为键,从字典convert_dict中取出阿拉伯数字
        alb_number = convert_dict[english_number]
        result += alb_number
    print(result)

最终搞定了,但是那部分源码为啥看不见却能匹配到真的现在也不知道,而且注意class后面的属性是会实时变化的,不能用来定位。这一点非常的坑。

 

posted @ 2020-06-15 14:25  猪啊美  阅读(2305)  评论(0)    收藏  举报