2013-05-31 17 views
0

我需要經常從形式的網站,獲取並解析XML數據:爲什麼蟒蛇的urllib2的urlopen返回的東西從瀏覽器不同的API調用

https://api.website.com/stuff/getCurrentData?security_key=blah 

我不能發佈安全的,因爲實際的連接數據的性質。當我把這個URL放到我的瀏覽器(Safari)中時,我返回了XML。

當我通過urllib2調用它時,我得到垃圾。

f = urllib2.urlopen("https://api.website.com/stuff/getCurrentData?security_key=blah") 
s = f.read() 
f.close() 
s 
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xc5\x96mo\xda0\x10\xc7\xdf\xf7SX\xbc\xda4\x15\xc7y\x00R\xb9\xae\xfa\xb4U\x1a-\x150M{5y\xe1\x06V\x13\x079\x0e\x14>\xfd\x9c\x84\xb0\xd2\xa4S\xa4L\xe5\x95\xef\xeeo 

這篇文章Urllib's urlopen breaking on some sites (e.g. StackApps api): returns garbage results似乎是一個類似的問題,但它指的是JSON而不是XML。按照說明來查看標題,我認爲我得到的是GZIP數據。 {我做了測試建議,張貼在這裏}

req = urllib2.Request("https://api.website.com/stuff/getCurrentData?security_key=blah", 
         headers={'Accept-Encoding': 'gzip, identity'}) 
conn = urllib2.urlopen(req) 
val = conn.read() 
conn.close() 
val[0:25] 
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xc5\x96]o\xda0\x14\x86\xef\xfb+,\xae6M' 

在那個崗位,有一些建議,這可能是一個局部問題,所以我想一個示例站點。

f = urllib2.urlopen("http://www.python.org") 
s = f.read() 
f.close() 
s 
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n <meta http-equiv="content-type" content="text/html; charset=utf-8" />\n <title>Python Programming Language &ndash; Official Website</title>\n 

這工作得很好,所以我認爲它與我實際試圖訪問的站點API有關。

此帖子Why does text retrieved from pages sometimes look like gibberish?建議我可能需要用「Selenium」做點什麼,但是那時海報說這個問題「固定了自己」,這並不能幫助我找出問題所在。

我無法使用python下載安全數據嗎? 除了urlib2和url打開之外,我需要使用不同的東西嗎?

我在Mac OSX上運行的Python 2.7 10.7.5

+0

檢查標題;服務器是否返回*壓縮*數據? –

+0

我不知道你的意思,@MartijnPieters - 我還是這個新手。但是......當我要求標題時,這就是我要求的標題''接受編碼':'gzip,identity'}' – jessi

+0

這些是你發送的標題。請檢查'conn.info()。headers'。 –

回答

2

您正在檢索GZIPped壓縮數據;服務器明確告訴你它與Content-Encoding: gzip。要麼使用zlib庫來解壓縮數據:

import zlib 

decomp = zlib.decompressobj(16 + zlib.MAX_WBITS) 
data = decomp.decompress(val) 

或使用支持透明減壓如果響應標頭指示壓縮已被使用,像requests庫。

+0

優秀! zlib可以工作,但我會追查可能是更乾淨的解決方案的請求。我早些時候嘗試瞭解請求,但我並不完全確定這會比'urllib2'和'urlopen'更好。 – jessi

+0

@Jessi:'requests'遠比'urllib2'清潔。 :-) –

1

'\x1f\x8b\'確實是gzip的魔法頭,所以你得到的gzip回數據。

在第二個例子中,你明確接受gzip的編碼數據,更改到'Accept-Encoding': 'identity',看看它是否有差別。

+0

當我在接受中刪除gzip時,@LennartRegebro獲得了相同的東西。 'req = urllib2.Request(「https://api.website.us/stuff/getCurrentData?security_key=blah」, headers = {'Accept-Encoding':'identity'}) conn = urllib2.urlopen( req) val = conn.read() conn。close() val [0:25] '\ x1f \ x8b \ x08 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x03 \ xc5 \ x96Qo \ xda0 \ x10 \ xc7 \ xdf \ xfb) x9e6M'' – jessi

+0

我以爲他們看起來很熟悉@MartijnPieters。這是發生了什麼。 'conn.info()。headers ['Date:Fri,2013年5月31日14:13:01 GMT \ r \ n', '服務器:Apache/2.2.14(Ubuntu)\ r \ n', 'X -Powered-By:PHP/5.3.2-1ubuntu4.18 \ r \ n', '內容編碼:gzip \ r \ n', '內容長度:645 \ r \ n', '連接:關閉\ r \ n', 'Content-Type:text/xml \ r \ n']'所以,它絕對看起來像gzip – jessi

+1

@Jessi:很難說沒有測試,但在我看來,服務器壞了並會一直髮送gzip。你必須解壓縮它。 http://stackoverflow.com/questions/3947120/does-python-urllib2-will-automaticly-uncompress-gzip-data-from-fetch-webpage(甚至更好,因爲Martijn建議,使用請求)。 –

相關問題