起點 字數 反 反爬蟲
阿新 • • 發佈:2018-10-31
起點 字數 反 反爬蟲
如何 獲取這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)
結果: