起点 字数 反 反爬虫

版权声明:欢迎转载,请标明文章出处 https://blog.csdn.net/IT_arookie/article/details/83180875

起点 字数 反 反爬虫

如何 获取这5个数字呢???
在这里插入图片描述

字数对应的源代码如下:
在这里插入图片描述

说明一下:

这是起点的一种反爬措施,起点有自己的数字库,在每次打开网页或刷新网页时,这一串数字都会改变,想要去和数字一 一对应都不可能,但是这一串数字和与之解析的数字库是对应的,只要找到对应的数字库,解析一下,就可以形成映射关系:

提取 5串 字符串和对应的数字库

在这里插入图片描述
注意:不要用解析器去解析,直接用正则表达式去提取:

	response = requests.get(url).text
 	pattern = re.compile('</style><span.*?>(.*?)</span>',re.S)
    #  获取当前页面所有被字数字符
    numberlist = re.findall(pattern, response)
    # 获取当前包含字体文件链接的文本
    reg = re.compile('<style>(.*?)\s*</style>',re.S)
    fonturl = re.findall(reg,response)[0]
    # 通过正则获取当前页面字体数字库的链接
    url = re.search('woff.*?url.*?\'(.+?)\'.*?truetype', fonturl).group(1)

numberlist :得到5个数字对应的字符列表
url :得到数字库的链接

解析数字库:

ontTools是一个用Python编写的用于操作字体的库。该项目包括TTX工具,可以将TrueType和OpenType字体转换为XML文本格式,也称为TTX。它支持TrueType,OpenType,AFM以及Type 1和某些Mac特定格式。

from fontTools.ttLib import TTFont
from io import BytesIO  #StringIO就是在内存中创建的file-like Object,常用作临时缓冲
def get_font(url):
    time.sleep(1)
    response = requests.get(url)
    font = TTFont(BytesIO(response.content))
    cmap = font.getBestCmap()  #返回unicode cmap字典可用的字体
    font.close()
    return cmap

可以得到一串数字和英文单词相对应的字典:
cmap: { 100543: ‘seven’, 100545: ‘period’, 100546: ‘nine’, 100547: ‘zero’,
100548: ‘five’, 100549: ‘one’, 100550: ‘six’, 100551: ‘eight’,
100552: ‘four’, 100553: ‘two’, 100554: ‘three’
}

只要新建一个新的英语与数字对应的字典,:
WORD_MAP = {‘zero’: ‘0’, ‘one’: ‘1’, ‘two’: ‘2’, ‘three’: ‘3’,
‘four’: ‘4’, ‘five’: ‘5’, ‘six’: ‘6’, ‘seven’: ‘7’,
‘eight’: ‘8’, ‘nine’: ‘9’, ‘period’: ‘.’}

形成映射:就可以轻松解决字数问题


附加代码:

import requests, json, time, re
from pyquery import PyQuery as pq
from fontTools.ttLib import TTFont
from io import BytesIO
import random
import time

def get_font(url):
    time.sleep(1)
    response = requests.get(url)
    font = TTFont(BytesIO(response.content))
    cmap = font.getBestCmap()
    font.close()
    return cmap

def get_encode(cmap, values):
    WORD_MAP = {'zero': '0', 'one': '1', 'two': '2', 'three': '3', 'four': '4', 'five': '5', 'six': '6', 'seven': '7',
                'eight': '8', 'nine': '9', 'period': '.'}
    word_count = ''
    list = values.split(';')
    list.pop(-1)
    for value in list:
        value = value[2:]
        key = cmap[int(value)]
        word_count += WORD_MAP[key]
    return word_count

def get_nums(url):
    # 获取当前页面的html
    time.sleep(1)
    response = requests.get(url).text
    #doc = pq(response)
    pattern = re.compile('</style><span.*?>(.*?)</span>',re.S)
    #  获取当前页面所有被字数字符
    numberlist = re.findall(pattern, response)
    # 获取当前包含字体文件链接的文本
    reg = re.compile('<style>(.*?)\s*</style>',re.S)
    fonturl = re.findall(reg,response)[0]
    # 通过正则获取当前页面字体文件链接
    url = re.search('woff.*?url.*?\'(.+?)\'.*?truetype', fonturl).group(1)
    cmap = get_font(url)
    print('cmap:',cmap)
    num_list = []
    for a in numberlist:
        num_list.append(get_encode(cmap, a))
    return num_list


def main(url):   # 为外界提供一可以调取的接口
    num_list = get_nums(url)
    return num_list

if __name__=='__main__':
	url='https://book.qidian.com/info/1115277'
	num_list = main(url)
	print(num_list)

结果:
在这里插入图片描述

时间:2018/10/19

猜你喜欢

转载自blog.csdn.net/IT_arookie/article/details/83180875