2015-11-02 68 views
2

我想下載和使用urllib和xlrd來操作xls文件。python下載和使用xls文件的問題

的數據是從URL http://profiles.doe.mass.edu/search/search_export.aspx?orgCode=&orgType=5,12&runOrgSearch=Y&searchType=ORG&leftNavId=11238&showEmail=N

我使用Python 2.7的到來,xlrd 0.9.4,urllib的1.17,我在Mac上。

我可以使用此代碼成功下載文件。

saveLocation = home_dir+"/test/" 
fileName = "data.xls" 
page = <the url given above> 
urllib.urlretrieve(page, saveLocation+fileName) 

我然後嘗試打開該文件使用xlrd

wb = xlrd.open_workbook(saveLocation+fileName) 

但得到的錯誤

XLRDError: Unsupported format, or corrupt file: Expected BOF record; found '\r\n\r\n<htm' 

這告訴我,該文件沒有下載作爲一個真正的xls文件。 我可以在Excel中打開文件,並且不會彈出警告或兼容性錯誤。 奇怪的是,如果我然後將文件(在Excel中)保存爲Excel 97-2004,則xlrd錯誤消失。所以看起來Excel會「修復」文件中的任何錯誤。

所以我的問題是,我如何「修復」在Python中的文件或下載數據在xlrd將識別適當的格式?

我也嘗試下載文件作爲xlsx文件,並使用openpyxl但得到類似的錯誤。 openpyxl說它不是一個有效的zip文件。 我也嘗試使用不同的方法,如請求下載數據。

謝謝。

編輯: 使用@ DSM提供的信息,我能夠下載和使用Excel文件。這是我使用的代碼。

dfs = pd.read_html(fileLocation+fileName, index_col = 7, header=0)[0] 
writer = pd.ExcelWriter(fileLocation+fileName) 
dfs.to_excel(writer,"Sheet1") 
writer.save() 

當時我能夠訪問該文件作爲一個真正的Excel文件

ws = pd.read_excel(fileLocation+fileName, 0) 
+0

在Windows,Excel中通知我正是如此:HTTP: //imgur.com/YkcuAWu IME這對於非Excel應用程序創建的文件是很常見的(例如,將緩衝區寫入文本文件,然後用xls擴展名命名)。該問題通常通過在Excel應用程序中打開文件,保存/保存並關閉文件來解決。 –

+0

關於openpyxl,如果它是.xls格式,它是**不是** ZIP文件(xlsm,xlsx,xlsb等等,都是ZIP存檔 - 舊的.xls擴展名不是)。 –

+0

我在Mac上沒有看到任何此類警告。 是的,正如我在我的描述中提到的,如果我在Excel中打開文件並重新保存它,問題就會消失。所以這個問題仍然適用,我需要做些什麼來以編程方式解決這個問題。不,我沒有嘗試使用openpyxl的xls文件。正如你在上面看到的,我說過我試着將它作爲一個zip格式的xlsx文件下載。所以openpyxl抱怨說這不是一個有效的zip格式。 – Adrian

回答

2

由於<htm位應暗示,這真的是在XML的方式提供的數據,儘管名稱.xls。 (在你最喜歡的編輯器中手動查看數據頭幾乎總是值得檢查,看看實際情況是什麼,當它看起來很難閱讀。)有時這可能是一個真正的麻煩來處理,但幸運的是,在這裏我們可以只需使用read_html閱讀:

>>> url="http://profiles.doe.mass.edu/search/search_export.aspx?orgCode=&orgType=5,12&runOrgSearch=Y&searchType=ORG&leftNavId=11238&showEmail=N" 
>>> dfs = pd.read_html(url) 
>>> len(dfs) 
1 
>>> dfs[0].iloc[:5,:5] 
                0   1 \ 
0           Org Name Org Code 
1  Abby Kelley Foster Charter Public (District) 04450000 
2           Abington 00010000 
3 Academy Of the Pacific Rim Charter Public (Dis... 04120000 
4          Acton (non-op) 00020000 

         2      3    4 
0    Org Type    Function Contact Name 
1  Charter District Charter School Leader  Brian Haas 
2 Public School District   Superintendent Peter Schafer 
3  Charter District Charter School Leader Chris Collins 
4 Public School District   Superintendent Glenn Brand 

仔細看,我們看到,我們可以使用第0行的頭,所以:

>>> df = pd.read_html(url, header=0)[0] 
>>> df.iloc[:5, :5] 
              Org Name Org Code \ 
0  Abby Kelley Foster Charter Public (District) 4450000 
1           Abington  10000 
2 Academy Of the Pacific Rim Charter Public (Dis... 4120000 
3          Acton (non-op)  20000 
4         Acton-Boxborough 6000000 

       Org Type    Function Contact Name 
0  Charter District Charter School Leader  Brian Haas 
1 Public School District   Superintendent Peter Schafer 
2  Charter District Charter School Leader Chris Collins 
3 Public School District   Superintendent Glenn Brand 
4 Public School District   Superintendent Glenn Brand