美文网首页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