質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.11%

seleniumでスクレイピングしたデータをsqlite3を使ったデータベースで一つ一つfor文で回してスクレイピングしたデータを取得していきたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 596

score 13

前提・実現したいこと

こんにちわ。python初学者です。
seleniumでスクレイピングしたデータをsqlite3を使ったデータベースで一つ一つfor文で回してスクレイピングしたデータを取得していきたいのですが、下記のようなエラーが出てしまいます。シンタックスエラーということでいろいろコードを見直しても直りません。
そして、スクレイピングはできているようなのですが、データベースに格納することができません、、、これは根本的に大幅にコードが間違っているんでしょうか?(テーブルとカラムはできてそうです。)
下記のようなエラーはどこのコード部分を直せば良いでしょうか??すいませんお力いただきたいです。
よろしくお願いします。

発生している問題・エラーメッセージ

Traceback (most recent call last):
  File "/Users/uu/Pycha/so/sample.py", line 50, in <module>
    insert_data(table_create, test)
  File "/Users/uu/Pycha/so/sample.py", line 41, in insert_data
    c.execute(insert, date)
sqlite3.OperationalError: near "<": syntax error
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import sqlite3

options = Options()
options.headless = True
options.add_argument('--headless')

db = "sample.db"
conn = sqlite3.connect(db)
c = conn.cursor()
table_name = "テーブル名"


def get_date():
    driver = webdriver.Chrome(options=options)
    driver.get("webサイトURL")
    selector = '要素'


    element = driver.find_elements_by_css_selector(selector)
    for a in element:
        b = a.get_attribute("href")
        print(b)

    date_element = "要素"
    date = driver.find_elements_by_css_selector(date_element)
    for c in date:
        d = c.text
        print(d)


def tab(ta):
    t = """create table if NOT EXISTS {} (we varchar(64), date varchar(32));""".format(ta)
    c.execute(t)


def inda(ta, date):
    insert = 'insert into {} (we, date) values (?,?);'.format(ta, date)
    c.execute(insert, date)
    conn.commit()

    s = 'select * from {};'.format(table_name)
    for a in c.execute(s):
        print(a)
        conn.close()


tab(table_name)
test = get_date()
inda(tab, test)
Python sqlite3

試したこと

関数なしでコードを書きましたがそちらでも詰まってしまいました。

def inda(ta, date):
    insert = 'insert into {} (we, date) values (?,?);'.format(ta, date)
    print(insert)
    print(date)
    c.execute(insert, date)
    conn.commit()


この関数の中の
c.execute(insert, date)
の前に
print(insert)
print(date)
こちらを出力しましたが同じエラーが出てしまいした。。。

補足情報(FW/ツールのバージョンなど)

python3.7 mac10.15 pycharm

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • meg_

    2020/08/09 13:03

    エラーメッセージには「insert_data(table_create, test)」とありますが、質問のコード中にはこの一文はありません。エラー発生場所は別のスクリプトなのでしょうか?

    キャンセル

  • sakanaku

    2020/08/09 13:09

    すいません、改善前のコードで実行していました。
    先ほどの実行したらまた別のシンタックスエラーが出ちゃいました、、
    /Users/uu/Pycha/so/venv/bin/python
    /Users/uu/Pycha/so/samp.py
    Traceback (most recent call last):
    File "/Users/uu/Pycha/so/samp.py", line 55, in <module>
    tab(table_name)
    File "/Users/kawamuraryuu/PycharmProjects/training-soh/situmon.py", line 38, in tab
    c.execute(t)
    sqlite3.OperationalError: near "(": syntax error

    Process finished with exit code 1

    キャンセル

  • sakanaku

    2020/08/09 13:15

    /Users/uu/Pycha/so/venv/bin/python
    /Users/uu/Pycha/so/samp.py
    https://www.sample.com
    insert into <function tab at 0x110d9a5f0> (we, date) values (?,?);
    None
    Traceback (most recent call last):
    File "/Users/uu/Pycha/so/samp.py", line 56, in <module>
    inda(tab, test)
    File "/Users/uu/Pycha/so/samp.py", line 45, in inda
    c.execute(insert, date)
    sqlite3.OperationalError: near "<": syntax error

    Process finished with exit code 1

    何度もすいません、先ほどの上記の
    sqlite3.OperationalError: near "(": syntax error
    こちらのシンタックスエラーは改善できましたが、同じエラーは出てしまいます、、、

    キャンセル

回答 2

checkベストアンサー

+1

バグ1 inda() の引数誤り

inda() の第一引数にテーブル名をいれるような作りなのに、tab という関数を入れてしまっています。

INSERT文実行前にprint(insert) してみると、
insert into <function tab at 0x7fa3f3cec670> (we, date) values (?,?);
となっているので、これはSQLとしてありえないです。

バグ2 INSERT文の実行方法誤り

INSERT INTO テーブル名 (we, date) values (?, ?) というように ? を使ったところはいいのですが
? に入る値の指定を execute時にしないといけないのにそれが抜けています。

バグ3 get_dateが値を返さない

can110さんのご指摘の通り

とりあえず動きそうなコード

get_date以外を直してみました。

# indaは全文掲載
def inda(ta, we, date):
    # insert = 'insert into {} (we, date) values (?,?);'.format(ta, date)  # ここにdateは不要
    insert = 'insert into {} (we, date) values (?,?);'.format(ta)
    # c.execute(insert, date)     # ?が2個あるのに値が1個しかない
    c.execute(insert, [we, date]) # ? を使ったときの ? に入れる値はここで配列にして指定する
    conn.commit()
    print("committed")

    s = 'select * from {};'.format(table_name)
    for a in c.execute(s):
        print(a)
        # conn.close()   #ここでcloseしてしまったらデータが1件しか取れない。

    conn.close()  # 動くように移動しましたがcloseせずにプログラムの最後でしたほうがよいです


tab(table_name)
test = get_date()
inda(table_name, "we_no_data", "date_no_data") # とりあえず固定値にしています

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/09 15:48

    詳しいご回答ありがとうございます。
    先程、inda()の中のコードをご教授いただいたコードに変えさせてもらうと無事に空のデータですが、SQLが動いてそうです。ありがとうございます。
    ちなみになのですが、get_date()の返り値はどのようなのが妥当なのでしょうか??
    先程まで試行錯誤していたのですが、

    print(b)とprint(d)を削除して、関数の最後にreturn [(b, d )]
    としてもエラーがでてしまいます。
    すいません、今出先でエラー文を掲載することができません、、、
    もしよかったら簡単な返り値のアドバイスあればぜひお願いしたいです。
    よろしくお願いします。

    キャンセル

  • 2020/08/09 15:59 編集

    ごめんなさい、質問文とコードからスクレイピングの結果、何を取得したいのかわからないので
    なんとも言えません。

    質問の内容が変わってしまっているので、現状を整理する意味でも、新しく質問を立てた方が回答がつきやすいと思います。
    その際、サイトのURL等を伏せていらっしゃるのでどういうサイトからどういう情報を取得したいのか
    質問に書いていただけると回答がつきやすいと思います。

    キャンセル

  • 2020/08/09 20:21

    すいません、質問の仕方も難しいな。と感じていたそこのアドバイスまでいただき本当にいろいろと助かりました。
    いろいろとまずは自分でやってみてどうしても分からなかったらまた質問を立てようと思います。
    すいません、ありがとうございました。
    ありがとうございました。

    キャンセル

+1

tab(table_name)
test = get_date()
inda(tab, test)


inda(tab, test)にてtabという関数を渡しているため提示エラーが発生しています。
おそらくtable_nameを渡すべきではないでしょうか?

またget_data関数は何もreturnしていないのでtestにはNoneが代入されます。
適切な値を返す必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/09 15:52

    table_nameを渡してコードを上記のアドバイスをいただいてデータベースが空ではありますが機能している感じになりました。ありがとうございます。

    ちなみになのですが
    >>またget_data関数は何もreturnしていないのでtestにはNoneが代入されます。
    適切な値を返す必要があります。

    こちらって現在の掲載しているコードみただけで返り値は分かるものでしょうか??
    もしよかったらご教授願いたいです。
    すいません、よろしくお願いします。

    キャンセル

  • 2020/08/09 17:48

    > こちらって現在の掲載しているコードみただけで返り値は分かるものでしょうか??
    はい。returnがない場合はNoneが返る仕様なので返り値はNoneであると分かります。

    キャンセル

  • 2020/08/09 20:20

    ご回答ありがとうございます。返り値をちゃんと指定できるよう勉強して動かしていきます。
    丁寧に教えていただきありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • seleniumでスクレイピングしたデータをsqlite3を使ったデータベースで一つ一つfor文で回してスクレイピングしたデータを取得していきたい