上次數(shù)獨(dú)(旁友數(shù)獨(dú)會(huì)伐啦?python秒解數(shù)獨(dú)了解下伐啦?
<https://www.cnblogs.com/moonhmily/p/11312887.html>
)后,老王好像從哪里得到了風(fēng)聲,跟我說(shuō)少往他們家?guī)淇伺啤馑祭锬愕募彝ッ芏际且驗(yàn)橐桓睋淇伺瓶?br>
行,那我這段時(shí)間先歇一歇,來(lái)日方長(zhǎng)……
那閑著也是閑著,不能去隔壁了,也不能讓小胖這雙手停下來(lái)不是……
那就上點(diǎn)評(píng)網(wǎng)找找妹子樂(lè)趣,然后就發(fā)現(xiàn)點(diǎn)評(píng)的反爬做的是真厲害。各個(gè)方面的反爬都有涉及,今天我們主要來(lái)看一下字體反爬這個(gè)玩意兒。
演示環(huán)境
* 操作系統(tǒng):windows10
* python版本:python 3.7
* 代碼編輯器:pycharm 2018.2
* 使用模塊:requests,json,re,fontTools
什么是字體反爬?
首選我們先來(lái)看一下點(diǎn)評(píng)網(wǎng)的評(píng)論信息。
從這里可以看到,網(wǎng)頁(yè)上顯示的文字和源碼中顯示的文字有些出入,并不是一一對(duì)應(yīng),那繼續(xù)查看sources中的代碼。
可以看到,評(píng)論中的某些文字點(diǎn)評(píng)網(wǎng)做了特殊處理,這就是所謂的字體反爬。
抓取數(shù)據(jù)
前面的步驟,我們已經(jīng)知道點(diǎn)評(píng)網(wǎng)對(duì)評(píng)論內(nèi)容做了處理,至于是如何處理,這里我們先不管,還是先把數(shù)據(jù)拿到再說(shuō)。要是數(shù)據(jù)都沒(méi)有拿到,還怎么對(duì)數(shù)據(jù)進(jìn)行處理呢?
首先使用谷歌的network,對(duì)所有請(qǐng)求進(jìn)行抓包。然后隨便搜索一個(gè)評(píng)論中的某些東西,找到返回的評(píng)論數(shù)據(jù)請(qǐng)求。這里我使用評(píng)論人的名字進(jìn)行搜索,找到其中的請(qǐng)求。有沒(méi)有覺(jué)得這個(gè)請(qǐng)求就是返回的評(píng)論數(shù)據(jù)呢。那來(lái)驗(yàn)證下。因?yàn)檫@里返回的是一個(gè)json數(shù)據(jù),可以借助在線json數(shù)據(jù)查看工具,方便我們對(duì)內(nèi)容進(jìn)行查看。
將數(shù)據(jù)復(fù)制下來(lái),然后在瀏覽器中輸入網(wǎng)址json.cn
接著就能看到解析出來(lái)的json數(shù)據(jù)。
經(jīng)過(guò)分析,我們知道所有的評(píng)論數(shù)據(jù)都在['reviewAllDOList']
,這個(gè)集合里裝了當(dāng)前頁(yè)面前10人的評(píng)論數(shù)據(jù)。這樣就可以通過(guò)列表遍歷的方式拿到相應(yīng)的數(shù)據(jù)。
點(diǎn)擊這個(gè)url的headers,找到請(qǐng)求的url,準(zhǔn)備獲取數(shù)據(jù)。
注意:
*
這個(gè)獲取到的url只能使用一會(huì)兒,過(guò)一會(huì)就會(huì)變化。如果一直使用這個(gè)url請(qǐng)求,后面就會(huì)得不到數(shù)據(jù)。所以后續(xù)當(dāng)請(qǐng)求不到數(shù)據(jù)的時(shí)候,就需要刷新網(wǎng)頁(yè),獲取一個(gè)新的url。因?yàn)閡rl中有個(gè)_token參數(shù)是每次變化的。
* 然后下面框中的內(nèi)容也必須在請(qǐng)求頭中添加上去,否則也還是得不到數(shù)據(jù)。
* 這里的重點(diǎn)是在字體反爬,所以其他的一些反爬在這里就不進(jìn)行贅述了。
至此就找到請(qǐng)求的評(píng)論接口數(shù)據(jù),直接請(qǐng)求這個(gè)url,就能得到我們想要的數(shù)據(jù)。
import requests import json import re def get_page_info(): #
首先分析網(wǎng)頁(yè),找到返回評(píng)論數(shù)據(jù)的url,這個(gè)url就會(huì)直接返回評(píng)論數(shù)據(jù)了,但是urlt中的token是會(huì)變化的,只能用一會(huì)兒,我也不知道一會(huì)兒是好久,得不到數(shù)據(jù)了就換url吧
url =
'http://www.dianping.com/ajax/json/shopDynamic/allReview?shopId=131013635&cityId=1604&shopType=10&tcv=7bbq1hdmsj&_token=eJxVTstugkAU%2FZe7nsBcBlBIulBrGxC0MmATTReACoSCFIg4Nv33Thu66Oq8k%2FMJrXMEGymlOhK4nlqwARWqmECg72RimAZOkFkTauoE0v%2BehRqBpN09gn1glkEmhv72YwRSH9BgJpma0hmpJqmmE%2B2348gK5H3f2Ko6DINyLOK6KepMSS%2BV2uWXRkWGFJnJDHkF5KQK5URiOWI8Yv%2BnfflddrsiqyU7ubeQd3r3cQ78Loyof58HQlgrzjXhpejxiHn3Zb%2BO%2BHUjFtOZCMrkOc%2Fi6lYlWbZbrLKeJ1u6RqfxUuaHhWitZb0Oy4RHrnveV0X6%2FhQ0VbPZvu5FOZ%2B91Oi4wwN8fQMlVWIi&uuid=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755&platform=1&partner=150&optimusCode=10&originUrl=http%3A%2F%2Fwww.dianping.com%2Fshop%2F131013635'
# 定義模擬請(qǐng)求頭 headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
'Cookie': 'cy=8; cye=chengdu;
_lxsdk_cuid=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b;
_lxsdk=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b;
_hc.v=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755; s_ViewType=10;
__utmz=1.1565010551.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
_lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic;
__utma=1.1978331348.1565010551.1565010551.1565161172.2; __utmc=1;
_lxsdk_s=16c6b1cf413-8ae-d6-7b8%7C%7C31',
'Referer':'http://www.dianping.com/shop/131013635', 'Connection': 'keep-alive',
} # 使用requests庫(kù)請(qǐng)求url,得到數(shù)據(jù)json數(shù)據(jù) result_json_str =
requests.get(url,headers=headers).text # 應(yīng)為返回的數(shù)據(jù)是里面包含富文本數(shù)據(jù),所以首先使用正則表達(dá)式刪除標(biāo)簽
result_json_str = re.sub('<.*?>','',result_json_str) #
json數(shù)據(jù)其實(shí)就是一個(gè)字符串,所以我們需要先將json轉(zhuǎn)化為python能操作的字典 result =
json.loads(result_json_str) # 分析得到的數(shù)據(jù),得到我們需要的所有評(píng)論在result['reviewAllDOList']里面
all_review = result['reviewAllDOList'] # 遍歷得到的所有評(píng)論 for review in all_review: #
得到用戶名 username = review['user']['userNickName'] # 得到評(píng)論內(nèi)容 content =
review['reviewDataVO']['reviewBody'] # 這里我們就是簡(jiǎn)單的顯示出內(nèi)容就是了,沒(méi)有進(jìn)行儲(chǔ)存
print('*'*30,'\n',username,content,'\n','*'*30)
運(yùn)行代碼,查看數(shù)據(jù),得到的數(shù)據(jù)果然就是經(jīng)過(guò)處理的。
破解字體反爬
上面雖然拿到了數(shù)據(jù),但是這些都是經(jīng)過(guò)處理之后的數(shù)據(jù),拿著完全不能用,所以還是得想辦法將他給破解下。
首先我們分析網(wǎng)頁(yè)得知,這些處理之后的數(shù)據(jù)class都為review,然后他的字體都是'PingFangSC-Regular-review'
猜想這就是點(diǎn)評(píng)網(wǎng)自己定義的字體。居然自定義了字體,那么網(wǎng)頁(yè)中肯定需要加載字體文件,所以果斷打開(kāi)network對(duì)字體文件進(jìn)行抓包。
搜索關(guān)鍵字'PingFangSC-Regular-review',就能找到相應(yīng)的信息。
我們可以看到,點(diǎn)評(píng)網(wǎng)有許多個(gè)自定義的字體,這里只需要找自己想要的字體文件即可,即找字體文件的url。只是這些字體文件一般都是.woff或者.ttf結(jié)尾的,我們可以將下面的滾動(dòng)條往右邊拖動(dòng),就能找到一個(gè).woff的url了。
發(fā)現(xiàn)這個(gè)url前面是以//開(kāi)始的,那嘗試直接在網(wǎng)址前面加https就行了,那么完整的url就是
https://s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/c667da25.woff
然后在瀏覽器中輸入這個(gè)網(wǎng)址,就可以下載一個(gè)后綴是.woff的字體文件。
為了方便查看字體文件的內(nèi)容,我們還需要下載fontCreator這個(gè)軟件。使用這個(gè)軟件打開(kāi)我們剛才下載的文件,就能夠看到相應(yīng)的值。fontCreator官網(wǎng)地址為
https://www.high-logic.com/font-editor/fontcreator
使用fontCreator打開(kāi)這個(gè)woff文件,如下圖所示。
我們得把這里面所有的文字按順序都寫出來(lái),并用一個(gè)列表保存,空的數(shù)據(jù)使用''表示。
是的,你沒(méi)有看錯(cuò),將這些文字全部寫下。
這些就是字體的形狀,我們已經(jīng)認(rèn)識(shí)了這些字,但我們還得讓程序也認(rèn)識(shí)這些字,當(dāng)然你也可以使用機(jī)器學(xué)習(xí)來(lái)識(shí)別這些文字,注意:一定要按順序來(lái),不能遺漏,不然的話對(duì)應(yīng)關(guān)系會(huì)出錯(cuò),替換出來(lái)的結(jié)果也就會(huì)出錯(cuò)。
我們把文字敲出來(lái)之后,然后需要得到字體形狀對(duì)應(yīng)的名字,對(duì)應(yīng)代碼字符串。這里需要使用fontTools這個(gè)第三方庫(kù)來(lái)處理字體文件。
from fontTools.ttLib import TTFont def get_font_map(): #
這個(gè)字體文件需要先析網(wǎng)頁(yè),找到這個(gè)url,然后下載下來(lái)到本地,然后使用TTFont()加載字體文件 # 字體文件的名字 font =
TTFont('76d0609c.woff') # 得到cmap 字體對(duì)應(yīng)代碼->字體名字 font_cmap = font.getBestCmap() #
得到所有的字體名字 font_names = font.getGlyphOrder() #
這個(gè)文字是先使用fontCreator軟件打開(kāi)字體文件,然后查看到字體,從而得到的數(shù)據(jù) texts = [
'','','1','2','3','4','5','6','7','8', '9','0','店','中','美','家','館','小','車','大',
'市','公','酒','行','國(guó)','品','發(fā)','電','金','心',
'業(yè)','商','司','超','生','裝','園','場(chǎng)','食','有',
'新','限','天','面','工','服','海','華','水','房',
'飾','城','樂(lè)','汽','香','部','利','子','老','藝',
'花','專','東','肉','菜','學(xué)','福','飯','人','百',
'餐','茶','務(wù)','通','味','所','山','區(qū)','門','藥',
'銀','農(nóng)','龍','停','尚','安','廣','鑫','一','容',
'動(dòng)','南','具','源','興','鮮','記','時(shí)','機(jī)','烤',
'文','康','信','果','陽(yáng)','理','鍋','寶','達(dá)','地',
'兒','衣','特','產(chǎn)','西','批','坊','州','牛','佳',
'化','五','米','修','愛(ài)','北','養(yǎng)','賣','建','材',
'三','會(huì)','雞','室','紅','站','德','王','光','名',
'麗','油','院','堂','燒','江','社','合','星','貨',
'型','村','自','科','快','便','日','民','營(yíng)','和',
'活','童','明','器','煙','育','賓','精','屋','經(jīng)',
'居','莊','石','順','林','爾','縣','手','廳','銷',
'用','好','客','火','雅','盛','體','旅','之','鞋',
'辣','作','粉','包','樓','校','魚(yú)','平','彩','上',
'吧','保','永','萬(wàn)','物','教','吃','設(shè)','醫(yī)','正',
'造','豐','健','點(diǎn)','湯','網(wǎng)','慶','技','斯','洗',
'料','配','匯','木','緣','加','麻','聯(lián)','衛(wèi)','川',
'泰','色','世','方','寓','風(fēng)','幼','羊','燙','來(lái)',
'高','廠','蘭','阿','貝','皮','全','女','拉','成',
'云','維','貿(mào)','道','術(shù)','運(yùn)','都','口','博','河',
'瑞','宏','京','際','路','祥','青','鎮(zhèn)','廚','培',
'力','惠','連','馬','鴻','鋼','訓(xùn)','影','甲','助',
'窗','布','富','牌','頭','四','多','妝','吉','苑',
'沙','恒','隆','春','干','餅','氏','里','二','管',
'誠(chéng)','制','售','嘉','長(zhǎng)','軒','雜','副','清','計(jì)',
'黃','訊','太','鴨','號(hào)','街','交','與','叉','附',
'近','層','旁','對(duì)','巷','棟','環(huán)','省','橋','湖',
'段','鄉(xiāng)','廈','府','鋪','內(nèi)','側(cè)','元','購(gòu)','前',
'幢','濱','處','向','座','下','県','鳳','港','開(kāi)',
'關(guān)','景','泉','塘','放','昌','線','灣','政','步',
'寧','解','白','田','町','溪','十','八','古','雙',
'勝','本','單','同','九','迎','第','臺(tái)','玉','錦',
'底','后','七','斜','期','武','嶺','松','角','紀(jì)',
'朝','峰','六','振','珠','局','崗','洲','橫','邊',
'濟(jì)','井','辦','漢','代','臨','弄','團(tuán)','外','塔',
'楊','鐵','浦','字','年','島','陵','原','梅','進(jìn)',
'榮','友','虹','央','桂','沿','事','津','凱','蓮',
'丁','秀','柳','集','紫','旗','張','谷','的','是',
'不','了','很','還','個(gè)','也','這','我','就','在',
'以','可','到','錯(cuò)','沒(méi)','去','過(guò)','感','次','要',
'比','覺(jué)','看','得','說(shuō)','常','真','們','但','最',
'喜','哈','么','別','位','能','較','境','非','為',
'歡','然','他','挺','著','價(jià)','那','意','種','想',
'出','員','兩','推','做','排','實(shí)','分','間','甜',
'度','起','滿','給','熱','完','格','薦','喝','等',
'其','再','幾','只','現(xiàn)','朋','候','樣','直','而',
'買','于','般','豆','量','選','奶','打','每','評(píng)',
'少','算','又','因','情','找','些','份','置','適',
'什','蛋','師','氣','你','姐','棒','試','總','定',
'啊','足','級(jí)','整','帶','蝦','如','態(tài)','且','嘗',
'主','話','強(qiáng)','當(dāng)','更','板','知','己','無(wú)','酸',
'讓','入','啦','式','笑','贊','片','醬','差','像',
'提','隊(duì)','走','嫩','才','剛','午','接','重','串',
'回','晚','微','周','值','費(fèi)','性','桌','拍','跟', '塊','調(diào)','糕' ] font_name_map = {} # 將
字體名字 和 我們查看到的值 組成一個(gè)字典 for index,value in enumerate(texts):
font_name_map[font_names[index]] = value return font_cmap,font_name_map
這里我還是很貼心的給大家畫(huà)了一個(gè)圖來(lái)解釋其中的對(duì)應(yīng)關(guān)系。
這樣就得到了字體的對(duì)應(yīng)關(guān)系,但是code是一個(gè)整數(shù),而網(wǎng)頁(yè)上顯示的是類似這樣的數(shù)據(jù),這需要幾步轉(zhuǎn)化下:
1、將code變成16進(jìn)制
2、將最前面的0替換為
3、在最后面添加一個(gè);
所以我們也把code按照這個(gè)規(guī)則進(jìn)行轉(zhuǎn)換,然后使用re模塊。只要找到這樣的一個(gè)code,就直接替換為文字。這樣就能夠拿到準(zhǔn)確的數(shù)據(jù)了。
所以,我們最后的get_page()函數(shù)的代碼如下所示
def get_page(font_names_map=None,font_cmap=None): #
首先分析網(wǎng)頁(yè),找到返回評(píng)論數(shù)據(jù)的url,這個(gè)url就會(huì)直接返回評(píng)論數(shù)據(jù)了,但是urlt中的token是會(huì)變化的,只能用一會(huì)兒,我也不知道一會(huì)兒是好久,得不到數(shù)據(jù)了就換url吧
url =
'http://www.dianping.com/ajax/json/shopDynamic/allReview?shopId=131013635&cityId=1604&shopType=10&tcv=txgmn7z01d&_token=eJxVj81ugkAUhd9ltp3A%2FCskXag1DQq2MmBSTReAOhIEEYg6Nn33Do1ddHXO%2Fe45yb1foPG2wMUIIYYhuOwa4AJsIUsACLrWbLjgRGBHcIdzCLJ%2FTPABhSBtVi%2FA3TCC4ICzzx6EZt5gTgUcCkMelhhLGCS%2FGc9EwKHrate2r9ertc2Tqs4rZWWn0m4Pp9rGFCNMBeXmFGAqZdRXCKOQDFgPih4YTR7a%2Fc2BecKU2lxVxu1mt0i2rD3vw6CNYhTcx6HWzlxKov0M%2BzKm%2Fn3aLWJ5edOT4UiHRfp6UEl5K1OlVpO56mS6RAvs1X5GgyjXjTOtFlGRyng226%2BPR1nwp2S9uhUfda7Go3d99jz0DL5%2FANI8Y5M%3D&uuid=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755&platform=1&partner=150&optimusCode=10&originUrl=http%3A%2F%2Fwww.dianping.com%2Fshop%2F131013635'
# 定義模擬請(qǐng)求頭,注意,得不到數(shù)據(jù)的時(shí)候,也要將Cookie的值進(jìn)行替換 headers = { 'User-Agent':'Mozilla/5.0
(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/75.0.3770.142 Safari/537.36', 'Cookie': 'cy=8; cye=chengdu;
_lxsdk_cuid=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b;
_lxsdk=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b;
_hc.v=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755; s_ViewType=10;
__utmz=1.1565010551.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
_lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic;
__utma=1.1978331348.1565010551.1565010551.1565161172.2;
_lxsdk_s=16c70ded480-ab0-fe2-71%7C%7C2',
'Referer':'http://www.dianping.com/shop/131013635', 'Connection': 'keep-alive',
} # 使用requests庫(kù)請(qǐng)求url,得到數(shù)據(jù)json數(shù)據(jù) result_json_str =
requests.get(url,headers=headers).text # 應(yīng)為返回的數(shù)據(jù)是富文本數(shù)據(jù),所以首先我們先去掉標(biāo)簽
result_json_str = re.sub('<.*?>','',result_json_str) # 遍歷 字體代碼->字體名字 這個(gè)字典(code
是一個(gè)數(shù)字) for code, name in font_cmap.items(): try: # 嘗試從 字體名字 -> 對(duì)應(yīng)值
這個(gè)字典中得到值,防止程序出現(xiàn)KeyError的錯(cuò)誤 text = font_names_map[name] except: pass else: #
分析網(wǎng)頁(yè)信息得知,將code變成16進(jìn)制,并且把最前面的0換成,在加上一個(gè)';'. 就是網(wǎng)頁(yè)加密了的字符竄了 #
這里就是將59322這樣的值變成類似``的值 code_str = str(hex(code)).replace('0',
'', 1) + ';' print(code, code_str, name, text) # 將得到的加密之后的字符串進(jìn)行替換為相應(yīng)的數(shù)據(jù) #
result_str = re.sub('需要替換的字符竄','替換為怎樣的字符串','從這個(gè)字符串里面查找') result_json_str =
re.sub(code_str, text, result_json_str) # 處理之后的數(shù)據(jù)使用json模塊變成字典 result =
json.loads(result_json_str) # 分析得到的數(shù)據(jù),得到我們需要的所有評(píng)論在result['reviewAllDOList']里面 #
因?yàn)檫@里有可能我們別識(shí)別出來(lái)是一個(gè)爬蟲(chóng)了,就會(huì)返回其他的數(shù)據(jù),比如說(shuō)你沒(méi)有登陸啊這樣的提示。所以這個(gè)時(shí)候我們就需要改變我們的額url了。然后重新運(yùn)行我們的爬蟲(chóng)了
try: all_review = result['reviewAllDOList'] except: print(result_json_str)
raise ValueError('爬取數(shù)據(jù)失敗') # 遍歷得到的所有評(píng)論 for review in all_review: # 得到用戶名
username = review['user']['userNickName'] # 得到評(píng)論內(nèi)容 content =
review['reviewDataVO']['reviewBody'] # 因?yàn)槲覀兊闹攸c(diǎn)是字體反爬,所以這里我們就是簡(jiǎn)單的顯示出內(nèi)容就是了
print('*'*30,'\n',username,":",content,'\n','*'*30)
呼。。。我們終于破解了點(diǎn)評(píng)網(wǎng)的字體加密。
最后還有一點(diǎn)需要注意,因?yàn)檫@個(gè)程序我當(dāng)天寫好之后,能成功的替換相應(yīng)的字符串,但是當(dāng)我第二天運(yùn)行程序的時(shí)候,缺不能替換了。
經(jīng)過(guò)分析發(fā)現(xiàn),原來(lái)是點(diǎn)評(píng)網(wǎng)每天(或許不是每天,每幾個(gè)小時(shí))應(yīng)該都會(huì)變換字體文件,然后code->name,name->形狀也就對(duì)應(yīng)不上了,但是形狀->值
一定是對(duì)應(yīng)上的,這個(gè)不會(huì)變化。
那么我們每次運(yùn)行之前,就直接找到字體文件對(duì)應(yīng)的url,然后先將這個(gè)文件下載保存到本地,再運(yùn)行我們的爬蟲(chóng)即可。
注意:這個(gè)字體文件的url是會(huì)變化的,也就是點(diǎn)評(píng)網(wǎng)的服務(wù)器上每個(gè)字體應(yīng)該存放了好幾個(gè)不同的字體文件。所以我們每次運(yùn)行都需要先去找到對(duì)應(yīng)的字體文件的url。
from urllib.request import urlretrieve def get_font_file(): url =
'https://s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/c667da25.woff'
urlretrieve(url,'font.woff')
這里說(shuō)一下urlretrieve函數(shù)的用法吧。
urlretrieve:將網(wǎng)絡(luò)上的文件下載下來(lái),保存到本地。第一個(gè)參數(shù)為url,第二個(gè)參數(shù)為保存到本地文件的文件名。
使用這個(gè)函數(shù)我們可以很方便的下載網(wǎng)絡(luò)上一些文件,圖片等。
最后我們來(lái)看一波運(yùn)行結(jié)果吧。
不得不服點(diǎn)評(píng)網(wǎng),反爬蟲(chóng)做的真是厲害。。。
關(guān)注公眾號(hào)「Python專欄」,更多有趣好玩的Python等著你喲~
全部代碼已上傳至Github:
https://github.com/MiracleYoung/You-are-Pythonista/tree/master/PythonExercise/App/dianping_spider
<https://github.com/MiracleYoung/You-are-Pythonista/tree/master/PythonExercise/App/dianping_spider>
熱門工具 換一換
