關於Python json解析過程遇到的TypeError: expected string or buffer
關於Python json解析過程遇到的問題:(爬取天氣json數據所遇到的問題http://tianqi.2345.com/)
part.1
url——http://tianqi.2345.com/t/wea_history/js/201708/60061_201708.js
返回的數據如下:
這就尷尬了,直接json.loads是返回錯誤的。
對比了其他網頁返回的——http://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&count=20&cur_tab=1
是不是格式問題:多了var……
於是乎谷歌解決辦法:
1、將所有‘變成” 2、添加“”(因為字典的鍵格式不標準,比如ymd沒有雙引號的)3、json前處理好數據 比如截斷var weather_str={city:‘新河‘,tqInfo:這部分
url = ‘http://tianqi.2345.com/t/wea_history/js/201708/60061_201708.js‘ r = requests.get(url).text s=r.split("tqInfo:")[1] s=s.split(",maxWendu")[0] s=s.replace("‘",‘"‘) s =re.sub(r‘[a-zA-Z]+‘,lambda x:‘"‘+x.group(0)+‘"‘,s) print s data = json.loads(s) for i in data: print i[‘aqi‘]
ok,經過數據清洗處理,勉強能用。
但是好奇怪,為什麽返回的json數據是這樣的?比較大型的網頁也這樣馬虎?難道是為了反爬蟲的設置? 帶著這些問題,我們進入下一個環節
--------------------------------------------------
part.2——selenium+phantomjs模擬爬取
from selenium import webdriver driver= webdriver.PhantomJS() #executable_path為你的phantomjs可執行文件路徑 driver.get("http://tianqi.2345.com/wea_history/60061.htm") #或得js變量的值 r = driver.execute_script("return weather_str")
print r
得到的結果:
註意:
返回的結果跟用requests返回的不一致,少了var weather_str…… 免除數據清洗的煩惱。
回到part1最後的疑問,也就是說不是網頁設計問題,其實是自己境界未到,還不知道這樣的處理方法。原來是這樣處理的,自己還是太膚淺了。
推測:應該有反爬蟲設置,返回json數據經過瀏覽器加載能正確呈現數據,直接requests得到數據不規整,限制獲取
很接近了,但是用json.loads還是返回錯誤TypeError: expected string or buffer
奇怪了 奇怪了 奇怪了,為什麽這樣?返回類型很標準了啊,正常可以解析啦
解決辦法:——谷歌+try嘗試輸出。
for i in data: print i
這玩意直接就是字典啊,輸出的都是字典鍵,然後詳細信息都在tqInfo裏面啊。
經過這樣處理,爬取的信息可以拿出來並且使用了,但是為什麽不用json呢?明明返回的是json數據啊
-------------------------------------------------------------
part.3——TypeError: expected string or buffer ——使用dumps和loads解決
百思不得其解。經過調試,最終發現,python中默認使用單引號表示字符串"‘" 所以當,用字符串符值以後,python會把雙引號轉換為單引號 也就是說: 先dumps轉換,再loads轉換,最終得出我們想要的結果,一步到位。from selenium import webdriver driver = webdriver.PhantomJS() #executable_path為你的phantomjs可執行文件路徑 driver.get("http://tianqi.2345.com/wea_history/60061.htm") #或得js變量的值 r = driver.execute_script("return weather_str") json_str = json.dumps(r) python_obj = json.loads(json_str) print python_obj for i in python_obj: print i
一波三折,終於把這個問題解決了。
關於Python json解析過程遇到的TypeError: expected string or buffer