はじめまして。
rare-sugarと申します。Pythonの初心者です。
前提・実現したいこと
i. 環境
- OS: Windows 10 Pro
- Python環境 Anaconda (version 1.7.2)
- Excel MS Office 2013 Pro
ii. 使用言語
Python Version 3.6.7
iii. 現状と問題点
A: ### 実現したいこと
あるサイトから、1から1,000(10,000)くらいまで連番のついた画像をSQLとfor文で一挙にスクレイピングし、いったんデータベース(SQLite or MySQLなど)に格納します。それらの画像データをデータベースからExcelへ読み込み・書き出しします。最後に、そのExcelシートをMS Accessからインポートして、Accessで画像データベースを作成します。
B ### 行数列数とデータ型
データベースもExcelも、2列1,000(10,000)行で、A列(フィールド1)のデータ型は整数型、B列(フィールド2)のデータ型はバイナリ型(SQLiteではBLOB型)。
発生している問題・エラーメッセージ
-
SQLとfor文で複数の画像を一挙にスクレイピングし、いったんデータベース(SQLite)に格納するところまでは、問題なく成功。
-
それらの画像データを読み込みExcelへ書き出しする時点で、失敗する。jupyter notebook上に表示させるくらいは可能だが、Excelの場合はやはりExcel独特のセル処理の問題があるので、何列何行目のセルにきちんと入らないとExcelデータにならないようです。
-
データ型を「リスト型」にすれば、for文でそのリストの中の画像を【add_image】メソッドで順次複数の画像を複数のセルの中に入れることは可能。現に、それでうまくいっています。
-
目的はリストではなくあくまでもデータベースとしてSQL文で上記の処理を実現したいのです。なにしろ、扱う画像ファイルは何千何万とあるのですから、何千何万ものリストを手入力で記述することは現実的ではありません。
-
リストやタプルを変数化して短いコードで膨大な画像をExcelに格納できるのであればそれでもいいですから、とにかくこれらの画像をExcelシートのセルに入れるPythonコーディングをお教えください。
-
なお、この投稿には多少の矛盾があることに今気づきました。なにぶん初心者ですので、ひらにご容赦くださいませ。
エラーメッセージ
<sqlite3.Cursor at 0x22ecc63ca40>
該当のソースコード
Python
ソースコード
データベースを新規作成(DBに【接続】)
Python
1conn = sqlite3.connect('pyDataBase.db')
「カーソル」を取得
c = conn.cursor()
SQLを実行
SQL
1c.execute(DROP_TABLE) 2c.execute(CREATE_TABLE1)
エラーメッセージ
OSError: cannot identify image file '11.png'
該当のソースコード
Python
1from openpyxl.drawing.image import Image 2from openpyxl.styles import Alignment 3 4xlImages = [{'id':1', 'Structures':'1.png'}, 5 {' id':2', 'Structures':'2.png, 6 {' id':3', 'Structures':'3.png, 7 {' id':4', 'Structures':'4.png, 8 {' id':5', 'Structures':'5.png, 9 {' id':6', 'Structures':'6.png, 10 {' id':7', 'Structures':'7.png, 11 {' id':8', 'Structures':'8.png, 12 {' id':9', 'Structures':'9.png, 13 {' id':10', 'Structures':'10.png ':''}] 14--------------------------------------------------------------------- 15**d = {} 16for x in xlImages 17 if x not in d.keys(): 18 d[x] = 1 19 else: 20 d[x] += 1 21** 22wbbk.save('New_myImages.xlsx') 23
試したこと
Python
1 2import sqlite3 3import openpyxl as px 4import sqlalchemy as sa 5import requests 6import cv2 7import pandas as pd 8import numpy as np 9 10dbName = 'pyDataBase.db' 11dbPath = r'C:\Users\shin\python_sqlite3\PubChem\pyDataBase.db' 12 13xlBook = 'xlDataBase.xlsx' 14xlPath = r'C:\Users\shin\python_sqlite3\PubChem\xlDataBase.xlsx' 15 16# テーブル作成をやり直したいときに備えます 17DROP_TABLE = "DROP TABLE IF EXISTS TABLE1" 18 19# テーブルの定義と作成 20CREATE_ TABLE1 = '''CREATE TABLE TABLE1 21(id INTEGER PRIMARY KEY, 22Structures BLOB)''' 23 24# データベースを新規作成(DBに【接続】) 25conn = sqlite3.connect(' pyDataBase.db ') 26# 「カーソル」を取得 27c = conn.cursor() 28# SQLを実行 29c.execute(DROP_TABLE) 30c.execute(CREATE_TABLE1) 31 32# 【INSERT文】に挿入するナマ・データを直接記述することはセキュリティ面で問題になるので、プレースホルダの?で代替 33# executeメソッドの引数にはSQL文と、かつ挿入する実際値をリストやタプルの形で指定。今回は【文字列のタプルであるrow】を指定 34 35wbpp = px.load_workbook(xlPath, data_only=True) 36wspp = wbpp[wbpp.sheetnames[0]] 37wspp.delete_rows(1) 38 39------------------------------------------------------------------------ 40 41for row in wspp.values: 42 sqlstr = "INSERT INTO TABLE1 ('id, 'Structures') VALUES(?,?)" 43 c.execute(sqlstr, row) 44conn.commit() 45 46if field1 == "": 47 print("field1(A列名、1番目の列名)は、空っぽです。列名を定義・作成してください") 48 49elif field1 != "" + field2 != "": 50 51 i =1 52 for i in range(1, 1000): 53 54 str_id = str(i) 55 56 PubChem_images = str_id + ".png" 57 58 url_PubChem = "https://pubchem.ncbi.nlm.nih.gov/image/imgsrv.fcgi?cid=" 59 60 url_PubChem_images = url_PubChem + str_id + "&t=l" 61 62 i = i + 1 63 64 for row in wspp.values: 65 sqlstr = "INSERT INTO TABLE1 ('id', 'Structurs') VALUES(?,?)" 66 67 imgUrl = "https://pubchem.ncbi.nlm.nih.gov/image/imgsrv.fcgi?cid=" + str(i) + "&t=l" 68 69 r = requests.get(imgUrl) 70 71 with open(str(i) + '.png', 'wb') as f: 72 73 img = Image(str(i) + '.png') 74 75 wsbk.add_image(img, 'B') 76 77 i = i + 1 78 79 c.execute(sqlstr, row) 80 81 wbbk.save('new_xlDataBase.xlsx) 82 83 conn.commit() 84 85 conn.close() # 接続解除 86
補足情報(FW/ツールのバージョンなど)
NCBI(米国立生物工学情報センター)の化学医学データベースサイトPubChemからidと2D画像データ(分子模型、化学組成)をスクレイピング。ちなみに、その1番目は、Acetylcarnitine。アセチルカルニチン(カルニチン誘導体の一種)で、2D画像データも参考のためUpしておきます。URLは、リンク内容