Python3爬取起點中文網閱讀量信息,解決文字反爬~~~附源代碼



起點中文網,在“數字”上設置了文字反爬,使用了自定義的文字文件ttf

通過瀏覽器的“檢查”顯示的是“□”,但是可以在網頁源代碼中找到映射后的數字
正則爬的是網頁源代碼,xpath是默認utf-8解析網頁數據,用xpath爬出來的也是方框,因此只能使用正則匹配爬取關鍵數字信息


本例以小說《斗羅大陸》為例 https://book.qidian.com/info/1115277,爬取閱讀量等數字信息


爬取思路:
1. 使用正則匹配爬取出網頁源代碼中的被設置反爬的數字信息(這里只能使用正則匹配)
2. 尋找數字的映射關系
  2.1 爬取出網頁中的字體文件地址,並下載這個文件

  2.2 使用軟件FontCreator(請度娘自行下載)打開文件,可以看到英文和數字的對應關系,寫入字典
  在本例中是按照習慣對應的(有可能有的文件自定義是打亂的)

#在fontcreator中查看此ttf文件中英文單詞與阿拉伯數字的映射關系,寫入字典
python_font_relation = {
    'one':1,
    'two':2,
    'three':3,
    'four':4,
    'five':5,
    'six':6,
    'seven':7,
    'eight':8,
    'nine':9,
    'zero':0,
    'period':'.'
}

 

  2.3 在python中安裝fontTools包,網頁源代碼中的數字與英文單詞的對應關系

def get_font(url):
    """
    獲取源代碼中數字信息與英文單詞之間的映射關系
    :param url: <str> 網頁源代碼中的字體地址
    :return: <dict> 網頁字體映射關系
    """
    time.sleep(1)
    response = requests.get(url)
    font = TTFont(BytesIO(response.content))
    web_font_relation = font.getBestCmap()
    font.close()
    return web_font_relation

結果是:

3. 通過2.2與2.3 可以看出來解碼需要兩步:

第一步:將正則匹配出來的6位數字先轉換成英文單詞

第二步:將英文單詞轉換成阿拉伯數字

然后就ok啦

 


源代碼:

1. 正則匹配沒有展開講,自行度娘吧

2. 有一些簡單的數據處理工作,細心點一步一步來,實在不行就每次都輸出看一下

  1 """
  2 起點中文網,在“數字”上設置了文字反爬,使用了自定義的文字文件ttf
  3 瀏覽器渲染不出來,但是可以在網頁源代碼中找到映射后的數字
  4 正則爬的是網頁源代碼 xpath是默認utf-8解析網頁數據;網頁源代碼有數據,使用瀏覽器"檢查"是方框,用xpath爬出來的也是方框
  5 以小說《斗羅大陸》為例 https://book.qidian.com/info/1115277
  6 """
  7 import requests, time, re, pprint
  8 from fontTools.ttLib import TTFont
  9 from io import BytesIO
 10 from lxml import etree
 11 
 12 #此代碼使用bs和xpath均無法爬出,需使用正則匹配
 13 #selector = etree.HTML(html_data.text)
 14 #word1 = selector.xpath('//div[2]/div[6]/div[1]/div[2]/p[3]/em[1]/span/text()')
 15 
 16 def get_font(url):
 17     """
 18     獲取源代碼中數字信息與英文單詞之間的映射關系
 19     :param url: <str> 網頁源代碼中的字體地址
 20     :return: <dict> 網頁字體映射關系
 21     """
 22     time.sleep(1)
 23     response = requests.get(url)
 24     font = TTFont(BytesIO(response.content))
 25     web_font_relation = font.getBestCmap()
 26     font.close()
 27     return web_font_relation
 28 
 29 
 30 #在fontcreator中查看此ttf文件中英文單詞與阿拉伯數字的映射關系,寫入字典
 31 python_font_relation = {
 32     'one':1,
 33     'two':2,
 34     'three':3,
 35     'four':4,
 36     'five':5,
 37     'six':6,
 38     'seven':7,
 39     'eight':8,
 40     'nine':9,
 41     'zero':0,
 42     'period':'.'
 43 }
 44 
 45 def get_html_info(url):
 46     """
 47     解析網頁,獲取文字文件的地址和需要解碼的數字信息
 48     :param url: <str> 需要解析的網頁地址
 49     :return:    <str> 文字文件ttf的地址
 50                 <list> 反爬的數字,一維列表
 51     """
 52     headers = {
 53         'User-Agent': 'User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
 54     }
 55     html_data = requests.get(url, headers=headers)
 56     # 獲取網頁的文字ttf文件的地址
 57     url_ttf_pattern = re.compile('<style>(.*?)\s*</style>',re.S)
 58     fonturl = re.findall(url_ttf_pattern,html_data.text)[0]
 59     url_ttf = re.search('woff.*?url.*?\'(.+?)\'.*?truetype', fonturl).group(1)
 60 
 61     # 獲取所有反爬的數字
 62     word_pattern = re.compile('</style><span.*?>(.*?)</span>', re.S)#制定正則匹配規則,匹配所有<span>標簽中的內容
 63     numberlist = re.findall(word_pattern, html_data.text)
 64 
 65     return url_ttf,numberlist
 66 
 67 
 68 def get_encode_font(numberlist):
 69     """
 70     把源代碼中的數字信息進行2次解碼
 71     :param numberlist: <list> 需要解碼的一維數字信息
 72     :return:
 73     """
 74     data = []
 75     for i in numberlist:
 76         fanpa_data = ''
 77         index_i = numberlist.index(i)
 78         words = i.split(';')
 79         #print('words:',words)
 80         for k in range(0,len(words)-1):
 81             words[k] = words[k].strip('&#')
 82             #print(words[k])
 83             words[k] = str(python_font_relation[web_font_relation[int(words[k])]])
 84             #print(words[k])
 85             fanpa_data += words[k]
 86         #print(fanpa_data)
 87         data.append(fanpa_data)
 88     print(data[0],'萬字')
 89     print(data[1], '萬閱文總點擊')
 90     print(data[2], '萬會員周點擊')
 91     print(data[3], '萬總推薦')
 92     print(data[4], '萬周推薦')
 93    # return data
 94 
 95 """程序主入口"""
 96 if __name__=='__main__':
 97     url = 'https://book.qidian.com/info/1115277'  # 選取某一小說
 98     get_html_info(url)
 99     web_font_relation = get_font(get_html_info(url)[0])
100     pprint.pprint(web_font_relation)#格式化打印網頁文字映射關系
101     get_encode_font(get_html_info(url)[1])

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM