Python網(wǎng)絡(luò)爬蟲(chóng)過(guò)程中網(wǎng)頁(yè)json格式數(shù)據(jù)存儲(chǔ)你學(xué)會(huì)了嘛?
回復(fù)“書(shū)籍”即可獲贈(zèng)Python從入門(mén)到進(jìn)階共10本電子書(shū)
大家好,我是Python進(jìn)階者。
一、前言
前幾天在Python白銀群有個(gè)叫【Rr】的粉絲問(wèn)了一個(gè)關(guān)于Python網(wǎng)絡(luò)爬蟲(chóng)過(guò)程中網(wǎng)頁(yè)json格式數(shù)據(jù)存儲(chǔ)的問(wèn)題,這里拿出來(lái)給大家分享下,一起學(xué)習(xí)。
二、解決過(guò)程
她一開(kāi)始將response的內(nèi)容都寫(xiě)在txt文件了,存儲(chǔ)的數(shù)據(jù)也不是json格式,看上去著實(shí)有點(diǎn)讓人抓狂的感覺(jué)。

當(dāng)然最后還是解決,這里給出【皮皮】和【月神】的代碼,如下所示:
with?open('Rr.txt',?'r',?encoding='utf-8')?as?f:
????for?line?in?f.readlines():
????????#?regex?=?re.compile('"summary":"(.*?)"',?re.S)
????????regex?=?re.compile('desc":"(.*?)","desc_module"',?re.S)
????????result?=?re.findall(regex,?line)
????????for?item?in?result:
????????????print(item)
其實(shí)后來(lái)想起來(lái),上次我和瑜亮老師給她看了這個(gè)網(wǎng)頁(yè),所以還是有點(diǎn)印象。我感覺(jué)她這么處理還是有點(diǎn)復(fù)雜了,不是說(shuō)不好,確實(shí)可行,我只是覺(jué)得可以從網(wǎng)頁(yè)上,直接reponse.json(),去取response['data']['desc'],之后直接存txt,一步到位,這樣更推薦。這里額外加入一個(gè)小插曲,下次在群里問(wèn)問(wèn)題的時(shí)候,可以貼代碼,不然挨個(gè)看你截圖手敲,實(shí)在是讓人頭大。用【瑜亮老師】的話(huà)說(shuō):你的代碼也不是軍事機(jī)密,不用這么藏著掖著[doge][doge]。
下面一起來(lái)看看【瑜亮老師】給的代碼吧。
import?requests
import?re
from?bs4?import?BeautifulSoup?as?bs
url?=?"https://scdn.gongyi.qq.com/json_data/data_detail/54/detail.37754.js"
resp?=?requests.get(url)
text?=?resp.text.replace('\\/',?'/')
text?=?text.encode('utf-8').decode('unicode_escape')
regex?=?re.compile('"detail_top_img":null,"desc":"(.*?)","desc_module"',?re.S)
result?=?re.findall(regex,?text)
page?=?bs(result[0],?"lxml")
print(page.text)
【瑜亮老師】只是在粉絲【Rr】的代碼上做了簡(jiǎn)單的修改,但是起到的代碼確實(shí)是立竿見(jiàn)影的,直接一步到位了。

后來(lái)還優(yōu)化了一版代碼,如下所示:
import?requests
from?bs4?import?BeautifulSoup?as?bs
import?json
url?=?"https://scdn.gongyi.qq.com/json_data/data_detail/54/detail.37754.js"
resp?=?requests.get(url)
text?=?resp.text.replace('\\/',?'/')
text?=?text.encode('utf-8').decode('unicode_escape')
page?=?bs(text,?"lxml")
data?=?page.text.replace('_cb_fn_proj_37754(',?'').replace(');',?'')
json_data?=?json.loads(data)
print(json_data["detail"]["desc"])
這個(gè)是使用json提取的。結(jié)果是一樣的,但是從代碼復(fù)用的角度上,會(huì)更好一些??梢苑奖闾崛∑渌胍淖侄危@個(gè)是導(dǎo)出來(lái)的json_data。話(huà)說(shuō)回來(lái),【瑜亮老師】一開(kāi)始也不是那么順利的,之前用json.loads之所報(bào)錯(cuò),個(gè)人認(rèn)為是因?yàn)樵创a中有類(lèi)似這樣的字段。< img src="http:\/\/p.qpic.cn\/gongyi\/748864bd25db5ee02a735eaad1c0fa2c013068bd5f3b273154f8aab95d4aae3f61f29b12d7211327\/500"\/>這里面有引號(hào),會(huì)導(dǎo)致loads時(shí)候出現(xiàn)報(bào)錯(cuò)。
總之,不管用什么方法,只要處理掉這些字符,就可以使用json.loads,比方說(shuō)這里.replace(');', '')需要剔除,json是類(lèi)似字典結(jié)構(gòu)的,結(jié)束的地方只能是 },不能有其他字符,不然會(huì)報(bào)錯(cuò),json....decoder....balabala。
你以為這就完事了?
No!
【月神】大佬發(fā)來(lái)一個(gè)秀代碼,如下所示:
import?requests
import?json
resp?=?requests.get('https://scdn.gongyi.qq.com/json_data/data_detail/54/detail.37754.js')
text?=?resp.text
text?=?text[text.find('(')?+?1:?text.rfind(')')]
print(json.loads(text)['detail']['desc'])
這個(gè)代碼中text = text[text.find('(') + 1: text.rfind(')')]這行代碼比較難理解,實(shí)現(xiàn)的效果也是提取指定格式的內(nèi)容。
運(yùn)行效果如下圖所示:

不過(guò)話(huà)說(shuō)回來(lái),長(zhǎng)時(shí)間爬取還是加上headers好一點(diǎn),不然爬蟲(chóng)也太高調(diào)了。P
三、總結(jié)
大家好,我是Python進(jìn)階者。這篇文章基于粉絲提問(wèn),針對(duì)Python網(wǎng)絡(luò)爬蟲(chóng)過(guò)程中網(wǎng)頁(yè)json數(shù)據(jù)提取的問(wèn)題,給出了具體說(shuō)明和演示,針對(duì)存儲(chǔ)結(jié)果進(jìn)行優(yōu)化,給出了4個(gè)方法,順利地幫助粉絲解決了問(wèn)題!
最后感謝粉絲【Rr】提問(wèn),感謝【皮皮】、【瑜亮老師】、【??(這是月亮的背面)】、【dcpeng】和【沈復(fù)】大佬給出的示例和代碼支持,感謝粉絲【冫馬讠成】積極參與學(xué)習(xí)交流。

小伙伴們,快快用實(shí)踐一下吧!如果在學(xué)習(xí)過(guò)程中,有遇到任何問(wèn)題,歡迎加我好友,我拉你進(jìn)Python學(xué)習(xí)交流群共同探討學(xué)習(xí)。
-------------------?End?-------------------
往期精彩文章推薦:

歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入Python學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群】
萬(wàn)水千山總是情,點(diǎn)個(gè)【在看】行不行
/今日留言主題/
隨便說(shuō)一兩句吧~
