美文网首页Python
突破字体反爬!Python下载全网小说章节与内容!

突破字体反爬!Python下载全网小说章节与内容!

作者: 爱是一道光_e5f7 | 来源:发表于2021-03-04 13:44 被阅读0次

    在手机端浏览小说时,有时候开启无图模式发现部分文字加载不出来,还有的不能使用浏览自带的阅读模式进行阅读,也就是无法解析,所以进一步探究原因,最后发现是小说网站设置了字体反爬。

    刚开始网上提供的一些案例基本是"58同城"、抖音,还有一个电影网(忘记是啥了)。

    基本操作是:

    1.通过网页解析下载ttf或者woff文件,然后

    from fontTools.ttLib

    import TTFont

    font = TTFont('**.ttf')

    font.saveXML('**.xml')

    1

    2

    3

    4

    将ttf文件转换为xml文件方便查看;或者直接在FontCreate工具中查看。

    2.在xml文件的cmap中查看映射关系。

    其中code是网页中显示的编码,name或许是数字对应的unicode,可通过推测找到映射关系。

    被替换了要么是10个阿拉伯数字,要么ttf中直接有汉字对应的unicode码,根本行不通。

    最终的效果并不理想,因为不能直接从ttf文件以及fontTools库来解析汉字对应的unicode码,只能通过FontCreate程序来查看map code对应的汉字设置字典进行替换,所幸由于渲染等因素,需要替换的文字有100个,还可以接受,但是网站经常更新的话肯定吃不消,再进一步查找资料:

    反爬终极方案总结—字体反爬

    看了一下,看来还有很长的路要走,日常需求基本能够满足,用工具也差不多能达到效果,之后有进一步需求再继续学吧。

    顺便贴一下简易的代码

    #从FontCreate工具得知的映射关系

    # txt_dict = {

    #            '\ue800':'的','\ue801':'一','\ue802':'是','\ue803':'了','\ue804':'我',

    #            '\ue805':'不','\ue806':'人','\ue807':'在','\ue808':'他','\ue809':'有',

    #            '\ue80a':'这','\ue80b':'个','\ue80c':'上','\ue80d':'们','\ue80e':'来',

    #            '\ue80f':'到','\ue810':'时','\ue811':'大','\ue812':'地','\ue813':'为',

    #            '\ue814':'子','\ue815':'中','\ue816':'你','\ue817':'说','\ue818':'生',

    #            '\ue819':'国','\ue81a':'年','\ue81b':'着','\ue81c':'就','\ue81d':'那',

    #            '\ue81e':'和','\ue81f':'要','\ue820':'她','\ue821':'出','\ue822':'也',

    #            '\ue823':'得','\ue824':'里','\ue825':'后','\ue826':'自','\ue827':'以',

    #            '\ue828':'会','\ue829':'家','\ue82a':'可','\ue82b':'下','\ue82c':'而',

    #            '\ue82d':'过','\ue82e':'天','\ue82f':'去','\ue830':'能','\ue831':'对',

    #            '\ue832':'小','\ue833':'多','\ue834':'然','\ue835':'于','\ue836':'心',

    #            '\ue837':'学','\ue838':'么','\ue839':'之','\ue83a':'都','\ue83b':'好',

    #            '\ue83c':'看','\ue83d':'起','\ue83e':'发','\ue83f':'当','\ue840':'没',

    #            '\ue841':'成','\ue842':'只','\ue843':'如','\ue844':'事','\ue845':'把',

    #            '\ue846':'还','\ue847':'用','\ue848':'第','\ue849':'让','\ue84a':'道',

    #            '\ue84b':'想','\ue84c':'作','\ue84d':'种','\ue84e':'开','\ue84f':'美',

    #            '\ue850':'总','\ue851':'从','\ue852':'无','\ue853':'情','\ue854':'己',

    #            '\ue855':'面','\ue856':'最','\ue857':'女','\ue858':'但','\ue859':'现',

    #            '\ue85a':'前','\ue85b':'些','\ue85c':'所','\ue85d':'同','\ue85e':'日',

    #            '\ue85f':'手','\ue860':'又','\ue861':'行','\ue862':'意','\ue863':'动'}

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    import requests

    from bs4 import BeautifulSoup

    import bs4

    import time

    #字体反爬

    #2021-1-18

    #url = "14、名场面_公派婚姻[六零]-在线全免小说网"

    list_1 = [

                '\ue800','\ue801','\ue802','\ue803','\ue804',

                '\ue805','\ue806','\ue807','\ue808','\ue809',

                '\ue80a','\ue80b','\ue80c','\ue80d','\ue80e',

                '\ue80f','\ue810','\ue811','\ue812','\ue813',

                '\ue814','\ue815','\ue816','\ue817','\ue818',

                '\ue819','\ue81a','\ue81b','\ue81c','\ue81d',

                '\ue81e','\ue81f','\ue820','\ue821','\ue822',

                '\ue823','\ue824','\ue825','\ue826','\ue827',

                '\ue828','\ue829','\ue82a','\ue82b','\ue82c',

                '\ue82d','\ue82e','\ue82f','\ue830','\ue831',

                '\ue832','\ue833','\ue834','\ue835','\ue836',

                '\ue837','\ue838','\ue839','\ue83a','\ue83b',

                '\ue83c','\ue83d','\ue83e','\ue83f','\ue840',

                '\ue841','\ue842','\ue843','\ue844','\ue845',

                '\ue846','\ue847','\ue848','\ue849','\ue84a',

                '\ue84b','\ue84c','\ue84d','\ue84e','\ue84f',

                '\ue850','\ue851','\ue852','\ue853','\ue854',

                '\ue855','\ue856','\ue857','\ue858','\ue859',

                '\ue85a','\ue85b','\ue85c','\ue85d','\ue85e',

                '\ue85f','\ue860','\ue861','\ue862','\ue863']

    list_2 = [

                '的','一','是','了','我',

                '不','人','在','他','有',

                '这','个','上','们','来',

                '到','时','大','地','为',

                '子','中','你','说','生',

                '国','年','着','就','那',

                '和','要','她','出','也',

                '得','里','后','自','以',

                '会','家','可','下','而',

                '过','天','去','能','对',

                '小','多','然','于','心',

                '学','么','之','都','好',

                '看','起','发','当','没',

                '成','只','如','事','把',

                '还','用','第','让','道',

                '想','作','种','开','美',

                '总','从','无','情','己',

                '面','最','女','但','现',

                '前','些','所','同','日',

                '手','又','行','意','动']

    def crawl(url, pre_1=''):

        hd = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '

                            '(KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}

        r = requests.get(url,headers=hd)

        r.raise_for_status()

        r.encoding = r.apparent_encoding

        html = r.text

        soup = BeautifulSoup(html, "html.parser")  #解析

        #novel = soup.find('div',"con_top")('a')[2].text #小说名

        chapter = soup.find('h1').string    #小说章节

        print("正在下载章节:",chapter)

        content = soup.find('div', id="txt").text#小说内容

        content_list = list(content)

        #这个地方效率很低,但是不知道怎么处理,以下用的是最简单粗暴的遍历每个字

        length = len(content)

        for i in range(length):

            for j in range(100):

                if content_list[i] == '\u3000':

                    content_list[i] = '\n'

                elif content_list[i] == list_1[j]:

                    content_list[i]=list_2[j]

        content_s = ''

        content_s = ''.join(content_list)

        #print(content_s[0])

        #print(content_s)

        novel_name = 'novel.txt'

        with open(novel_name, 'a', encoding='utf-8') as f:

            f.write('\n'+chapter+'\n')

            f.write(content_s)

            f.close()

        pre = "14、名场面_公派婚姻[六零]-在线全免小说网"

        #next_url比较特殊,该小说网站比较特别的是一个章节有分几页,如果还在本章节,下一页的url是加上?page= 拼接

        #否则是下一章节的url

        next_url = soup.find('li', 'next')('a')[0].get('href')

        if len(next_url)>10:#换章节

            true_next = next_url

            #pre = next_url

            pre_1 = next_url

        else:#不换章节,拼上?page=

            if pre_1 == '':#第一章

                true_next = pre + next_url#初始url+ ?page=

            else:#非第一章

                true_next = pre_1 + next_url

        if next_url:

            return true_next,pre_1#如果是新章节,那么是正确的,如果是旧章节,返回是相加之后的

        else:

            return False

    if __name__=='__main__':

        url = "14、名场面_公派婚姻[六零]-在线全免小说网"#初始url

        url,pre_1 = crawl(url)

        while(1):

            time.sleep(1)  #爬取过快防止网站503

            url, pre_1 = crawl(url,pre_1)

    近期有很多朋友通过私信咨询有关Python学习问题。为便于交流,点击蓝色自己加入讨论解答资源基地

    相关文章

      网友评论

        本文标题:突破字体反爬!Python下载全网小说章节与内容!

        本文链接:https://www.haomeiwen.com/subject/svckqltx.html