1. 程式人生 > >關於Python json解析過程遇到的TypeError: expected string or buffer

關於Python json解析過程遇到的TypeError: expected string or buffer

inf 免除 replace 路徑 driver images ret script tro

關於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