実現したいこと
ダウンロードした.xlsxのファイルをpandasのデータフレームで開きたいです。
前提
大量の.xlsxファイルがあります。
これらは一度直接開いてから、上書き保存するとpandasで読み込めるのですが、
そのままpd.read_excelしても読み込めません。
どうやら中身が圧縮されたxmlファイルで構成されており、そのまま開けないようです。
発生している問題・エラーメッセージ
KeyError: "There is no item named '[Content_Types].xml' in the archive"
該当のソースコード
python
1import pandas as pd 2fname = 'file.xlsx' 3df = pd.read_excel(fname) 4print(df)
試したこと
中身はこのような階層でした。
encordingを変えたりもしましたが、読み込めませんでした。
どなたかヒントだけでも良いので助けていただきたいです。
python
1from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile 2import xml.etree.ElementTree as ET 3 4archive = ZipFile(fname) 5for _i in archive.infolist(): 6 print('zip info: {}'.format(_i.filename)) 7 8# 出力 9zip info: xl/worksheets/sheet1.xml 10zip info: _rels/.rels 11zip info: xl/styles.xml 12zip info: [content_types].xml 13zip info: xl/_rels/workbook.xml.rels 14zip info: xl/sharedstrings.xml 15zip info: xl/workbook.xml
補足情報①
pandasで問題なく読み込めるファイル(一度直接開いて上書き保存したもの)の階層を追記
一度上書き保存したら※のファイルが増えますが、なぜ増えるのかがわからないです。
zip info: [Content_Types].xml zip info: _rels/.rels zip info: xl/_rels/workbook.xml.rels zip info: xl/workbook.xml zip info: xl/styles.xml zip info: xl/theme/theme1.xml ※ zip info: xl/worksheets/sheet1.xml zip info: xl/sharedStrings.xml zip info: docProps/core.xml ※ zip info: docProps/app.xml ※
補足情報②
https://qiita.com/ty21ky/items/44d0f6079440247b8698
拡張子を.xlsxを.odsに変更して、掲載の試してみましたが
KeyError: '.ods'
となりました。
> ダウンロードした.xlsxのファイル
が、エクセルのファイルではないのではないですかね
https://teratail.com/questions/302735
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11190764806
ありがとうございます。
書き漏れており失礼いたしました。
ご紹介いただいたteratailのページは確認しており、以下のページを参考にしてみました。
https://qiita.com/ty21ky/items/44d0f6079440247b8698
拡張子を.xlsxを.odsに変更して、掲載の試してみましたが
KeyError: '.ods'
となりました。
この次(もしくは私の試し方が間違えているのか等)何を試していけば良いのか、もしアイディアがあればお伺いできたらと思います。
元のファイルはデータベースから自動でダウンロードしたものです。
> 以下のページを参考にしてみました。
https://qiita.com/ty21ky/items/44d0f6079440247b8698
拡張子を.xlsxを.odsに変更して、掲載の試してみましたが
KeyError: '.ods'
となりました。
は、質問を編集して追記してください
> 元のファイルはデータベースから自動でダウンロードしたもの
が、エクセルでも、odsでもない、さらに別のものとか
そのデータベースの仕様を確認した方がいいのではないですかね
ありがとうございました。
データベースの仕様書を再度確認してみます。
> 一度上書き保存したら※のファイルが増えます
> zip info: xl/theme/theme1.xml ※
> zip info: docProps/core.xml ※
zip info: docProps/app.xml ※
https://okumuralab.org/~okumura/stat/xlsx.html
によると、それらはエクセルで保存したら含まれるもののようです
「試したこと」の「# 出力」と、「補足情報」を比べたら、「※」が増えるだけでなく、順番も変わってますね
元の(エラーになる)ファイルにも
> zip info: [content_types].xml
があるのに
> KeyError: "There is no item named '[Content_Types].xml' in the archive"
となるのは、もしかすると、「[Content_Types].xml」が先頭じゃないとダメなのかも
(pandasのコード読んでないので、当てずっぽうですが)
ありがとうございます。
[Content_Types].xml]は、エラーは大文字なのですが、展開されるファイルは[Content_Types].xmlで小文字なので、それでないと言われているのだと思います。
教えていただいたサイトには、そのようなファイルはOpen Office XML」形式のファイルではなく、Libre OfficeやApache Open Officeで作成した「OpenDocument Spreadsheet」形式のファイルなのではとあったのですが、、、そこから先に進めておりません
そこまで予想できているなら
Excelで普通にxlsxを保存する→zipで展開→ファイル名を[content_types].xmlに変更→zipで圧縮して拡張子をxlsxに変更→pandasでエラーになるか検証
をして自分で再現テストができると思いました。(もう一つの仮説はファイルの順番)
もし再現するならば、しかるべき所にissueとして上げる/ファイル形式の仕様書を探す/pandasのコードを読む と進むのではないかと。
ありがとうございます。
ご提示いただいた検証を一度やってみます。
> [Content_Types].xml]は、エラーは大文字なのですが、展開されるファイルは[Content_Types].xmlで小文字
なるほど
それは見落としてました
https://github.com/python/cpython/blob/3.7/Lib/zipfile.py
の1365行目の「x = ZipInfo(filename)」で「x」に入ったデータで、1384行目の「self.NameToInfo[x.filename] = x」が実行され、「self.NameToInfo」に情報が入ってるはず
同じファイルの1428行目の「info = self.NameToInfo.get(name)」で、上記1384行目で入ったはずの情報がうまく取り出せないようで、「info」に「None」が入り、1431行目で、この質問のエラー「There is no item named...」が出てます
質問者さんが言うように、大文字・小文字の相違が原因かも
ありがとうございます。文字ミスってましたね、済みません。
xlsxファイルをpythonで展開→[content_types].xml
xlsxファイルをPCでopen後に上書き保存→xlsxファイルをpythonで展開→[Content_Types].xmlになり、ファイルも3つ増える。
大文字、小文字の相違もなのですが、この3つ増えるファイルを展開しないといけないのではないかと推測しているのですが、詰まっています。
> 3つ増えるファイルを展開しないといけないのではないかと推測
quickquipさんがコメントに書いた
・pythonで正常に読めるファイルを小文字に変えてみる
のと、その逆に
・pythonでエラーになるファイルを大文字に変えてみる(三つのファイルは足りないまま)
のとで、それぞれどうなるのか? を試してみたらいいと思います
> 元のファイルはデータベースから自動でダウンロードしたもの
> データベースの仕様書を再度確認してみます。
元がおかしなモノなので、この確認および
正しい.xlsxをダウンロードできるような方法を探すのが先だと思います。
エラーが出るのは展開前のxlsxファイルをpandasで読み込んだ際に発生するので、変えてみる事ができないのですが、一度展開してから変更して圧縮してみます。
あとは中身を再度確認していってみます。
> エラーが出るのは展開前のxlsxファイルをpandasで読み込んだ際に発生するので、変えてみる事ができない
が、私が書いた「pythonでエラーになるファイルを大文字に変えてみる(三つのファイルは足りないまま)」のことを指してるのなら、その手順にもquickquipさんがコメントに書いたように、ファイル名を大文字に変える前後に「zipで展開」と「zipで圧縮」が含まれます
quickquipさんがコメントに書いたことの「逆」というのは、「大文字←→小文字 の向き」のことだけで、それ以外の手順は同じです
(ただし、エクセルのファイルをzipで展開して、何か操作して、zipで圧縮する、ということをしたことが無いので、その状態でエクセルのファイルとして正しい状態に戻るのかは、よく知りません)
> 正しい.xlsxをダウンロードできるような方法を探すのが先
もちろん、それが可能なら、それが一番いいですよね
ただし、pythonではエラーが出るけど、エクセルでは読めるようなので、現状でもエクセル的には「正しい」のかもしれません
(正しくないけど読めてしまう、という可能性もありますが)
>ファイル名を大文字に変える前後に「zipで展開」と「zipで圧縮」が含まれます
>その状態でエクセルのファイルとして正しい状態に戻るのかは、よく知りません
ありがとうございます。私も正しく戻るのかやってみないと何ともですのでやってみます。
>正しい.xlsxをダウンロードできるような方法を探すのが先だと思います。
これはデータベンダーの仕様なのでどうしようもなさそうです、、。
また、PCで直接開いてから保存したら通常通りpandasで開けるので、ファイルが壊れている、というわけでもなさそうに、、、でももう一度ダウンロードも試してみます。
ありがとうございます。
> これはデータベンダーの仕様なのでどうしようもなさそうです、、。
どのような「ベンダー仕様」なのか不明ですが、以下の仕様と外れているものであれば
「.xlsxファイルではない」ので、わたしならベンダーに問い合わせて対応(修正)をお願いします。
https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
ありがとうございました。
どうやらファイル名が全て小文字で作成されているようで、、、なのでどのライブラリでもエラーになっていた様です。一応ベンダーには伝えておこうと思います。
大量に取得して、コードで前処理しようと思うとちょっと困る人いると思うので。
普通に手元のPCで開いて作業する分には大丈夫そうなんですが。
ありがとうございました
回答1件
あなたの回答
tips
プレビュー