<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python爬蟲遇到字體反爬?教你輕松搞定!

          共 5011字,需瀏覽 11分鐘

           ·

          2021-08-06 23:55


          人生苦短,快學(xué)Python

          大家在使用Python爬蟲時,經(jīng)常會遇到各種反爬問題。今天就以貓眼電影為例,看看如何解決其中的 字體反爬

          由于對于一部電影來說,它的票房和評分?jǐn)?shù)據(jù)是非常重要的,所以網(wǎng)站開發(fā)人員對它進(jìn)行了保護(hù),也就是字體反爬,今天的目標(biāo)是破解貓眼電影網(wǎng)站的字體反爬。

          一、需求分析

          我們是需要爬取論壇文本數(shù)據(jù),如下圖所示:

          部分網(wǎng)頁源碼展示:

          我們發(fā)現(xiàn)數(shù)據(jù)是不在網(wǎng)頁源碼里面,而是以一種特殊的字符存在的。

          二、發(fā)起請求

          import requests
          url = "https://maoyan.com/films/1298542"
          headers = {
              "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
          }
          r = requests.get(url,headers=headers)
          print(r.text)

          然后得到如下數(shù)據(jù)(部分?jǐn)?shù)據(jù)截圖):

          和網(wǎng)頁源碼里面的數(shù)據(jù)一樣,通過requests簡單請求之后發(fā)現(xiàn)評分,票房數(shù)據(jù)被特殊字符替換掉了,此時再次查看Elenments對應(yīng)的標(biāo)簽里的數(shù)據(jù),如下圖所示:

          由圖可以發(fā)現(xiàn)有的字被替換掉了,所以我們需要找到數(shù)字被替換的方式(規(guī)律),然后替換回去。

          三、替換規(guī)律

          通過上面分可知,該網(wǎng)站中使用的字體對應(yīng)的是stonefont,它是該網(wǎng)站為了反爬設(shè)置的自定義字體,它一定存在于style(樣式)標(biāo)簽里面:

          然后拿到url對應(yīng)屬性(xxx57..woff),它是不同于.ttf的字體文件,但是同樣可以使用FontCreator打開:

          //k3.autoimg.cn/g1/M02/D0/99/wKgHFVsUz1eAH_VRAABj9PS-ubk57..ttf

          注意:如果該屬性打不開文件,可以在屬性前加上 https://maoyan.com

          查看后發(fā)現(xiàn)是一個字體文件:

          然后打開字體查看文件,把字體文件拖拽進(jìn)去,如下圖所示:(使用軟件為FontCreator,可以查看字體的軟件)

          如果不想使用軟件,可以打開百度字體平臺網(wǎng)站,對應(yīng)頁面和軟件打開是一樣的

          粗略一看其實發(fā)現(xiàn)不了什么,所以我們需要使用fontTools第三方庫查看字體文件:

          from fontTools.ttLib import TTFont
          font = TTFont('./f0a30a4dda64b4f8f344858115f54fc92296 (1).woff')
          print(font.getGlyphOrder())

          結(jié)果如下圖所示:

          ['glyph00000''x''uniF4EF''uniF848''uniF88A''uniE7A1''uniE343''uniE137''uniF489''uniE5E2''uniF19B''uniE8CD']

          然后我們發(fā)現(xiàn)比如在先前的網(wǎng)頁源碼中發(fā)現(xiàn)的,

          &#xe7a1;.&#xf19b;  # 對應(yīng)網(wǎng)頁中的9.2

          然后由此查看后綴,9----e7a1,在上圖中

          四、數(shù)據(jù)抓取

          1、導(dǎo)包,我們使用re第三方庫解析

          import requests
          import re
          from fontTools.ttLib import TTFont

          2、定制一個類(Maoyan),以及初始化屬性設(shè)置:

          class MaoYan(object):
              def __init__(self):
                  self.url = 'https://maoyan.com/films/1298542'
                  self.headers = {
                      "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
                  }
                  self.font = TTFont('./f0a30a4dda64b4f8f344858115f54fc92296 (1).woff')
                  self.numList = ['6''3''7''9''8''0''4''2''5']

          3、相關(guān)方法設(shè)置

          發(fā)送請求獲取相應(yīng)

          def get_html(self, url):
              response = requests.get(url, headers=self.headers)
              return response.content

          處理字體文件

          def getNewList(self):
              newList = []
              glyList = self.font.getGlyphOrder()[2:]  # 前兩個數(shù)據(jù)是沒有用的,剔除
              for gly in glyList:
                  m = gly.replace('uni''&#x').lower() + ';' # replace字符替換
                  newList.append(m)

              return newList

          解析數(shù)據(jù)

          def parseData(self, data):
              for i in self.getNewList():
                  if i in data:
                      print(self.numList[self.getNewList().index(i)])
                      data = data.replace(i, self.numList[self.getNewList().index(i)])

              return data

          正則匹配以及最終輸出

          def start_crawl(self):
              html = self.get_html(self.url).decode('utf-8')
              # 正則匹配星級
              star = re.findall(r'<span class="index-left info-num ">\s+<span class="stonefont">(.*?)</span>\s+</span>', html)[0]
              print(star)
              star = self.parseData(star)

              print('用戶評分: %s 星' % star)

          4、最后運行:

          if __name__ == '__main__':
              maoyan = MaoYan()
              maoyan.start_crawl()

          結(jié)果如下,文字替換成功:

          由于票房數(shù)據(jù)和這個評分有著異曲同工之妙,所以這里不再贅述,感興趣的小伙伴可以去試一下。

          五、小結(jié)

          通常在2爬取一些網(wǎng)站的信息時,偶爾會碰到這樣一種情況:網(wǎng)頁瀏覽顯示是正常的,用 Python 爬取下來是亂碼,F(xiàn)12用開發(fā)者模式查看網(wǎng)頁源代碼也是亂碼。這種一般是網(wǎng)站設(shè)置了字體反爬。字體反爬是一種比較常見的反爬方式,因為很多網(wǎng)站的文字信息是比較重要的,像是前面提到的貓眼電影電影票房評分等數(shù)據(jù),非常重要,網(wǎng)站維護(hù)者當(dāng)然會把這種數(shù)據(jù)進(jìn)行反爬處理,只要好好分析,還是能夠抓取到目標(biāo)數(shù)據(jù)。

          注意點:

          1. 字符匹配以及替換,還有正則表達(dá)式的書寫規(guī)范
          2. 貓眼驗證,當(dāng)用戶頻繁的發(fā)起請求時,他會有一個驗證,滑塊驗證,這個時候最好使用selenium手動操作一下,然后就可以正常的請求數(shù)據(jù)。


          我們的文章到此就結(jié)束啦,如果你喜歡今天的Python 實戰(zhàn)教程,請持續(xù)關(guān)注Python實用寶典。

          有任何問題,可以在公眾號后臺回復(fù):加群,回答相應(yīng)紅字驗證信息,進(jìn)入互助群詢問。

          原創(chuàng)不易,希望你能在下面點個贊和在看支持我繼續(xù)創(chuàng)作,謝謝!

          點擊下方閱讀原文可獲得更好的閱讀體驗

          Python實用寶典 (pythondict.com)
          不只是一個寶典
          歡迎關(guān)注公眾號:Python實用寶典

          瀏覽 122
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩婷婷| 黄色影院在线观看 | 免费一级中文字幕 | 天天综合网,7799精品视频天天看 | 影音先锋成人在线资源 |