在執(zhí)行爬蟲項(xiàng)目的過程中,有時返回的不是一個html頁面而是json格式數(shù)據(jù)忧勿,此時對數(shù)據(jù)的解析非常重要杉女。
比如京東的評論數(shù)據(jù)、淘寶的評論數(shù)據(jù)鸳吸、人人貸的數(shù)據(jù)(https://www.we.com/lend/loanList!json.action?pageIndex=3)熏挎。
(一).Json格式數(shù)據(jù)的爬取
采用Python爬取數(shù)據(jù)可以采用Scrapy或者采用urllib,requests等兩種方法,顯然在這里采用第二種方式更為簡單晌砾。
步驟如下:
1坎拐、由于有分頁的情況,因此首先構(gòu)造帶分頁的url地址养匈。
urlbase ="https://www.we.com/lend/loanList!json.action?pageIndex="
urlList = []
#拼接要爬取的地址
for?i?in?range(1,52):
? ? ?url= urlbase +str(i)+"&_=1489560949549"urlList.append( url )
#循環(huán)抓取列表頁信息
2哼勇、采用request對以上的url進(jìn)行爬取
import ?requests
content=requests.get(url,headers=headers).content
在爬取的過程中,考慮到需要模擬真實(shí)的用戶呕乎,因此需要添加cookie或者h(yuǎn)eader參數(shù)积担。
(二).對爬取的json格式數(shù)據(jù)的解析
至此,數(shù)據(jù)已經(jīng)爬取下來猬仁,存放在contend里面帝璧,但是如何提出里面的關(guān)鍵數(shù)據(jù)非常重要。
為了能在瀏覽器中方便的瀏覽Json格式的數(shù)據(jù)湿刽,建議在chrome中添加一個擴(kuò)展程序JSONView的烁,使得其Json格式的數(shù)據(jù)能夠結(jié)構(gòu)化的顯示。比如人人貸的數(shù)據(jù)顯示如下叭爱。
對于這個數(shù)據(jù)的解析有兩種方式
1撮躁、采用正則表達(dá)式解析
比如我們要獲取“amount”的內(nèi)容,可以采用以下方式獲嚷蛭怼:
importre
##使用正則提取amount字段amount = re.findall(r'"amount":(.*?),', content)
其中content是爬取下來內(nèi)容把曼。
2、基于json格式進(jìn)行獲取
實(shí)際上json的數(shù)據(jù)格式與python的dict是有極大的類似之處漓穿。在python的importjson這個包里面提供了兩個經(jīng)典的預(yù)處理方法:
import json
dict_ = {1:2, 3:4,"55":"66"}
# test json.dumps
print type(dict_), dict_
json_str =json.dumps(dict_)
print "json.dumps(dict) return:"
print type(json_str), json_str
# test json.loads
print "\njson.loads(str) return"
dict_2 =json.loads(json_str)
print type(dict_2), dict_2
輸出為:
程序結(jié)果:
{'55': '66', 1: 2, 3: 4}
json.dump(dict) return:
{"55": "66", "1": 2,"3": 4}
json.loads(str) return
{u'55': u'66', u'1': 2, u'3': 4}
從上面的樣例可以看出兩個經(jīng)典的方法dumps和loads的作用分別為:
json.dumps
:將ptyhon的dict轉(zhuǎn)成str
json.loads:將str轉(zhuǎn)成python的dict類型
有了以上的基礎(chǔ)知識后嗤军,對于人人貸的數(shù)據(jù)可以直接采用如下方式處理:
for?url?in?urlList:
? ? //獲取內(nèi)容
? ?content=requests.get(url,headers=headers).content
? ?//采用json.loads方法將str轉(zhuǎn)換為dict類型
? ?con=json.loads(content)#獲取都到評論列表,因?yàn)橹斑€有很多的其他東西晃危,這些是不需要的
? ?//直接采用python中dict的數(shù)據(jù)獲取方法叙赚,取得loans列表,然后直接取得各個數(shù)據(jù)僚饭。
? ?commentList= con["data"]["loans"]
? ?for ??item?in ?commentList:
? ? ? ?loanId= item['loanId']
? ? ? title= item['title']
? ? ? amount= item['amount']
? ? ? interest= item['interest']?
? ? ? months= item['months']
備注:
采用第二種方式的時候要注意震叮,返回的數(shù)據(jù)是不是標(biāo)準(zhǔn)的json格式的數(shù)據(jù),如果不是標(biāo)準(zhǔn)的json格式數(shù)據(jù)鳍鸵,那么可能需要額外處理一下苇瓣。比如京東商品的評論數(shù)據(jù),
這是Apple iPhone 7 Plus (A1661) 128G亮黑色移動聯(lián)通電信4G手機(jī)的評論數(shù)據(jù)偿乖。
直接打開上面的鏈接后就會發(fā)現(xiàn)在jsonview下面并不是正規(guī)的json格式數(shù)據(jù)顯示击罪,那么對于這種數(shù)據(jù)類型哲嘲,可以采用正則表達(dá)式的方式來獲取,當(dāng)然也還是可以采用json轉(zhuǎn)換為dict方式來處理媳禁。
仔細(xì)分析爬下來的數(shù)據(jù):
原始頁面:
我們要爬取的是用戶評論數(shù)據(jù)眠副,而爬取下來的content并不是標(biāo)準(zhǔn)的json格式數(shù)據(jù),怎么辦竣稽,如上圖給出的提示囱怕,爬取下來的contend是把數(shù)據(jù)放到fetchJSON_comment98vv52063()里面了,而括號里面的數(shù)據(jù)則是標(biāo)準(zhǔn)的json格式數(shù)據(jù)丧枪。
因此對于此類的數(shù)據(jù)光涂,首先要正則表達(dá)是提出括號里面的數(shù)據(jù),然后再用loads方法轉(zhuǎn)換為python的dict類型數(shù)據(jù)進(jìn)行處理就可以了拧烦。
源碼如下:
#爬取
for?url ?in ?urlList:
? ? ? cont=requests.get(url,headers=headers,cookies=cookie).content
#這點(diǎn)非常重要忘闻,這里的正則表達(dá)式是取以數(shù)字或者字母開頭,后面緊跟()中的內(nèi)容 ??rex=re.compile(r'\w+[(]{1}(.*)[)]{1}')
? ?content=rex.findall(cont)[0]#取出括號中的東西恋博,這是一個標(biāo)準(zhǔn)的json格式數(shù)據(jù)
? ? con=json.loads(content,"gbk")
#獲取都到評論列表齐佳,因?yàn)橹斑€有很多的其他東西,這些是不需要的
? ? commentList= con['comments']
? ? for ?item ?in ?commentList:
? ? ? ? ?id= item['id']?
? ? ? ? content= item['content'].strip()
? ? ? ?referenceName= item['referenceName']
? ? ? ?productColor= item['productColor']
一個技巧:可以先嘗試提出()內(nèi)的數(shù)據(jù)到一些在線的json解析網(wǎng)站(http://www.bejson.com/)去看看json數(shù)據(jù)的排列格式债沮,這樣就更加清楚該怎么提取數(shù)據(jù)了炼吴。
(三)參考文獻(xiàn):
1、使用python抓取并分析數(shù)據(jù)—人人貸(urllib)
2 http://blog.csdn.net/yan_xing_an/article/details/46892105