吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 766|回复: 8
收起左侧

[讨论] python字体反爬求助

[复制链接]
XiaoZouYu 发表于 2022-5-22 12:34
一个python小菜鸟,在起点中文网上爬取月票数据,遇到了字体反爬,弄了好久才勉强弄出来了,麻烦大佬们给点建议,有更简单的方法分享下,救救孩子啊啊啊
[Python] 纯文本查看 复制代码
import re
import requests
from fontTools.ttLib import TTFont
from lxml import etree

if __name__ == '__main__':

    url_ = 'https://www.qidian.com/rank/yuepiao/'

    headers_ = {
        'Cookie': 'e1=%7B%22pid%22%3A%22qd_P_rank_01%22%2C%22eid%22%3A%22qd_C45%22%2C%22l1%22%3A5%7D; e2=%7B%22pid%22%3A%22qd_P_rank_01%22%2C%22eid%22%3A%22qd_C46%22%2C%22l1%22%3A5%7D; newstatisticUUID=1653031883_243064998; _csrfToken=SqNQc9cnJezKvfEbUcq8hUVBBpkKKZnStUjihiGS; fu=317266460; _gid=GA1.2.102240006.1653031887; e1=%7B%22pid%22%3A%22qd_p_qidian%22%2C%22eid%22%3A%22qd_A16%22%2C%22l1%22%3A3%7D; e2=%7B%22pid%22%3A%22qd_p_qidian%22%2C%22eid%22%3A%22qd_A16%22%2C%22l1%22%3A3%7D; _yep_uuid=437ba5a1-9bf2-cf11-e031-4198b9b208d2; _gat_gtag_UA_199934072_2=1; _ga_FZMMH98S83=GS1.1.1653183720.5.1.1653183739.0; _ga_PFYW0QLV3P=GS1.1.1653183720.5.1.1653183739.0; _ga=GA1.2.1828961077.1653031887',
        'Referer': 'https://www.qidian.com/rank/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
        'connection': 'close'
    }

    response_ = requests.get(url_,headers=headers_)

    str_data = response_.text

    # 把拿到的数据转换为xpath能够转化的数据
    html_obj = etree.HTML(str_data)
    # 解析书名
    title_list = html_obj.xpath('//h2/a/text()')
    # 解析月票数据,用xpath无法解析,考虑使用正则
    ticket_list = re.findall(r'</style><span class=".+?">(.*?)</span></span>月票</p>',str_data)
    # print(ticket_list)
    # 提取字体的url,用xapth不能直接获取,需要进一步用正则
    res_ = html_obj.xpath('//style/text()')[0]
    # print(res_)
    font_url = re.findall("format\('eot'\); src: url\('(.*?)'\) format\('woff'\)",res_)[0]
    # print(font_url)

    # 发送请求,获取字体加密文件
    font_response = requests.get(font_url,headers=headers_)
    # 保存获取到的字体加密文件
    with open('font_data.woff', 'wb') as f:
        f.write(font_response.content)
    # 解析字体加密文件
    font_obj = TTFont('font_data.woff')
    # 转换为能看懂的格式xml
    font_obj.saveXML('font_data.xml')
    # 获取其中的加密映射表
    camp_dict = font_obj.getBestCmap()
    # print(camp_dict)

    # 创建一个英文和数字匹配的字典,与加密数字匹配
    dict_number = {'one':'1','two':'2','three':'3','four':'4','five':'5','six':'6','seven':'7','eight':'8','nine':'9','zero':'0','preiod':'.',}
    for i in camp_dict:
        for j in dict_number:
            if camp_dict[i] == j:
                camp_dict[i] = dict_number[j]
    # print(camp_dict)

    # 因为我们在网页中拿到的加密有特殊字符混在其中,先去掉特殊字符
    for i in enumerate(ticket_list):
        new_ticket_list = re.findall('\d+',i[1])
        ticket_list[i[0]] = new_ticket_list
    # print(ticket_list)

    # 去掉特殊字符后与得到的映射表匹配出数字
    for i in ticket_list:
        for j in enumerate(i):
            for n in camp_dict:
                if j[1] == str(n):
                    i[j[0]] = camp_dict[n]
    # print(ticket_list)

    # 把拿到的列表中子列表的引号去掉
    ultimately_ticket_list = []
    for i in ticket_list:
        j = ''
        for k in i:
            j += k
        ultimately_ticket_list.append(j)
    # print(ultimately_ticket_list)

    rank_list = dict(zip(title_list,ultimately_ticket_list))
    print(rank_list)

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

cdsgg 发表于 2022-5-22 13:05
我怀疑你是过来秀技术的哈哈
区长 发表于 2022-5-22 14:10
 楼主| XiaoZouYu 发表于 2022-5-22 15:50
cdsgg 发表于 2022-5-22 13:05
我怀疑你是过来秀技术的哈哈

哈哈,并没有,发帖只是为了和大家讨论学习,寻找不同的方法。没有一丝丝秀的意思
cdsgg 发表于 2022-5-22 15:50
XiaoZouYu 发表于 2022-5-22 15:50
哈哈,并没有,发帖只是为了和大家讨论学习,寻找不同的方法。没有一丝丝秀的意思

我有一个例子 你可以参考一下
 楼主| XiaoZouYu 发表于 2022-5-22 15:51

真的没有啦
cdsgg 发表于 2022-5-22 15:52
XiaoZouYu 发表于 2022-5-22 15:50
哈哈,并没有,发帖只是为了和大家讨论学习,寻找不同的方法。没有一丝丝秀的意思

[Python] 纯文本查看 复制代码
def get_page_show_ret(mystr, bs64_str):
    font = TTFont(BytesIO(base64.decodebytes(bs64_str.encode())))
    # 可用于58 等字体加密的反爬爬取
    c = font['cmap'].tables[0].ttFont.tables['cmap'].tables[0].cmap
    ret_list = []
    for char in mystr:
        decode_num = ord(char)
        if decode_num in c:
            num = c[decode_num]
            num = int(num[-2:]) - 1
            ret_list.append(num)
        else:
            ret_list.append(char)
    ret_str_show = ''
    for num in ret_list:
        ret_str_show += str(num)
    return ret_str_show
 楼主| XiaoZouYu 发表于 2022-5-22 15:56
cdsgg 发表于 2022-5-22 15:52
[mw_shl_code=python,true]def get_page_show_ret(mystr, bs64_str):
    font = TTFont(BytesIO(base64 ...

感谢感谢,借鉴了
feiyu361 发表于 2022-5-23 11:17
666666,很好,学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-14 04:24

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表