url中能出现的字符_python爬虫,解决大众点评字符库反爬机制的经验
剛開始寫文章還希望大家可以喜歡,對于爬蟲只是個人整理出的方法,爬蟲大牛請嘴下留情。“”僅限學術交流,如有冒犯請聯系作者刪除“”話不多說,想分析天津地區餐飲行業的大致情況,要爬出(商鋪名稱,星級,評價條數,人均消費金額,菜系,商圈,團購活動等)。
可是在爬蟲時發現,這些數字都是以這類方框形式展示,再看源代碼,以&#xXXXX這種形式展示,這是反爬機制中的字體庫反爬,要把這些代碼轉化成前端看到的123或天津菜等數據。
感覺跟特工密碼一樣,真讓人興奮。要把這些代碼對應出真正的數字或漢字,需要把css內的woff字符庫爬出來。獲取的css鏈接類似如下:http://s3plus.sankuai.com/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/9a2072f4d3d2589da1b348aebb034c6c.css
在源代碼中找到這樣的內容,爬取下來
#爬取代碼如下 pattern=re.compile(r'//s3plus..*?.css') url=pattern.findall(html) url1=''.join(url) cssurl='http:'+url1css鏈接爬下來后打開看看,里面的內容,哇塞,這是什么神仙結構,可以看到里面有2種字符庫。
我之前遇到過里面有4種各不相同的字符庫,這里只有2種字符庫,簡單多了但是css內的字體文件一直在變,光抓下來一次woff文件是不夠的,既然這里實時變更,就要采取爬蟲實時抓取css、下載woff。
先把第一次爬取出來的css文件中的woff文件下載下來,上面截圖看的出里面有2個woff文件,是否要把所有的woff文件都下載下來呢?這要看我們都需要爬取下來什么內容,(商鋪名稱,星級,評價條數,人均消費金額,菜系,商圈,團購活動)這些內容看他們的class標簽,屬于2類,shopNum,tagname,在css文件中能查到這2個標簽,分別對應一個woff文件,也就是下載這2個woff文件即可。
下載下載woff文件代碼:
# 將css內對應shopNum,tagname標簽的font-family內容爬取出來 def css_url(html):pattern=re.compile(r'//s3plus..*?.css')url=pattern.findall(html)url1=''.join(url)cssurl='http:'+url1f=requests.get(cssurl)f.encoding='utf-8'f1=f.textshopnumfont=re.findall(r'@font-face{font-family: "PingFangSC-Regular-shopNum".*?shopNum{font-family: 'PingFangSC-Regular-shopNum';}',f1)shopnum=''.join(shopnumfont)tagnamefont=re.findall(r'@font-face{font-family: "PingFangSC-Regular-tagName".*?tagName{font-family: 'PingFangSC-Regular-tagName';}',f1)tagname=''.join(tagnamefont)return shopnum,tagname # 將對應標簽內的woff下載在本地 def unicode_dict(shopnum):shopnumlist = re.findall(r'//s3plus.meituan.net/v1/w+/font/w+.woff',shopnum)shopnumurl = "http:" + ''.join(shopnumlist)response_shopnumwoff = requests.get(shopnumurl).contentfontname = shopnumurl[-13:-5]h=open(fontname + '.woff', 'wb')h.write(response_shopnumwoff)h.close()現在先以shopNum標簽舉例,舉一反三tagname也就知道怎么處理了。下面就是關鍵,把爬取出來的一個woff文件做為基礎字符庫,通過FontCreator可以把編碼對應的數字或漢字顯示出來,下面是fontcreator打開woff文件后呈現出來的樣子。
但要把這些編碼和對應漢字轉換成.xls或.txt還需要一個圖像文字識別軟件,推薦在線https://zhcn.109876543210.com/,把fontcreator中內容截圖下來,用剛才的鏈接轉換成.csv,直接把代碼和對應的漢字都下載下來,方便直接生成字典(這是我的方法,可以根據自己的喜好來選擇下載的形式),
這里的是不是unie045和很像?只要把前面3個字符更換成uni就可以了?測試一下是真的可以的。那把編碼和漢字對應上,形成字典,再replace(’uni’,’&#x’)就能把網頁上的&#xXXXX轉換成漢字或數字了,就能爬取下來正確的內容了。
可這只能生成一個字典,前面說過css內的woff是不斷變換的,每個woff文件下載下來相同數字對應的編碼都不相同,如圖,
不可能每個woff文件都這樣生成一個字典,其他字符庫要怎么找到編碼對應的漢字或數字呢?這里需要用到TTFont,from fontTools.ttLib import TTFont,把woff文件存為xml,每個編碼都會生成這樣一個坐標系,雖然編碼不同,但是后面的坐標系是相同的,對應生成的數字或漢字也是相同的,這是一個切入點~
只要通過一個字符庫的xml找到坐標系和漢字、數字對應的關系,新爬下來的字符庫轉換成xml后,遍歷他的坐標系和已知字符庫的坐標系對上了,就把已知字符庫的漢字或數字賦值給新的字符庫,完成!
上代碼:
newfont = TTFont(fontname + '.woff') newfont.saveXML(fontname + '.xml') basefont = TTFont('1d7914a7.woff') unicodedict = {"unie046": "跟", "unif305": "塊", "unif230": "1", "unie713": "2", "unie86f": "3", "unie5f3": "4","unif235": "5", "unie7c3": "6", "unif558": "7", "unie383": "8", "unif5f6": "9", "unie8f4": "0","unieb6b": "店", "unie015": "中", "unif44f": "美", "unif4fe": "家", "unif5b5": "館", "unie6b4": "小","unif78b": "車", "unie0a1": "大", "unif191": "市", "unie5eb": "公", "unif33f": "酒","unif0a1": "行", "unie19a": "國", "unie075": "品", "unie4d5": "發", "unif2ed": "電", "uniea88": "金","uniec19": "心", "unie240": "業", "unif77e": "商", "unif87a": "司", "unief51": "超", "unie877": "生","uniebf3": "裝", "unied5e": "園", "unie0c0": "場", "unie723": "食", "unif167": "有", "uniec25": "新","unief2b": "限", "unieb71": "天", "unie36b": "面", "unie4e5": "工", "unie820": "服","unieb69": "海", "unie591": "華", "unif5ab": "水", "unif653": "房", "unie3d5": "飾", "unif48e": "城","unif042": "樂", "unie31f": "汽", "unif76c": "香", "unie056": "部", "unie5b9": "利", "unif860": "子","unie661": "老", "unif316": "藝", "unie714": "花", "unif101": "專", "uniedf8": "東", "unie66e": "肉","unif6eb": "菜", "unif897": "學", "unif2a7": "福", "unie148": "飯", "unif313": "人","uniedf7": "百", "unied1a": "餐", "unif7be": "茶", "unie32e": "務", "unie63b": "通", "unie45b": "味","unif397": "所", "unieda8": "H1", "unie761": "區", "unif6cf": "門", "unie424": "藥", "uniedc9": "銀","unif87c": "農", "unie462": "龍", "unie04a": "停", "unie610": "尚", "unif0ea": "安", "unie913": "廣","unie399": "鑫", "uniebb2": "—", "unie04b": "容", "unie21a": "動", "unie225": "南","unif024": "具", "unif165": "源", "unie259": "興", "uniecb3": "鮮", "unie4a3": "記", "unif109": "時","unif4ed": "機", "unie5c7": "烤", "unif276": "文", "unie538": "康", "unied4c": "信", "uniedca": "果","unif1d5": "陽", "unif6f9": "理", "unie83a": "鍋", "unif7e1": "寶", "unif094": "達", "unif18e": "地",....... } # 太長了做縮略,全部代碼后面會附上。 newfont_glyphNames=newfont.getGlyphNames()[1:-1] basefont_glyphNames=basefont.getGlyphNames()[1:-1] temp={} a=len(unicodedict) for i in range(0,a):for j in range(0,a):if newfont['glyf'][newfont_glyphNames[i]]==basefont['glyf'][basefont_glyphNames[j]]:temp[newfont_glyphNames[i].replace('uni','&#x').lower()]=unicodedict[basefont_glyphNames[j]]else:pass return temp通過上面幾步,基本上就可以把爬取下來的字段對應出正常的漢字或數字了,再保存到mysql中,結果如下。
整理思路:
1、 爬取出css鏈接,從css內解析出shopNum,tagname標簽的woof文件
2、 將下載下來的一個woff文件做為基礎,用fontcreator和誠華OCR,將編碼對應的漢字和數字整理成字典。
3、 將已知的字符庫用TTFont存為xml,用getGlyphNames()和if條件語句判斷新下載的字符庫和已知字符庫是否有相同的坐標系,有的話將字典內的值賦給新的字符庫的編碼,用replace(‘uni’,‘&#x’)將Unicode編碼轉換為網頁上的編碼,形成新的字典。
4、 通過以上方式生成2類字典,shopNum字典和tagname字典。
5、 將爬取出來的&#xXXXX這個格式的內容,區分匹配哪類字典,再將字典的值賦給對應的編碼,形成最終的前端顯示的文字或數字。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的url中能出现的字符_python爬虫,解决大众点评字符库反爬机制的经验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle昨日时间,。。今日,昨日,上
- 下一篇: 初识C++之函数重载、重写、重定义的区别