【问题标题】:is there any way to use the values from a list in an sql lite database有什么方法可以使用 sql lite 数据库中列表中的值
【发布时间】:2020-07-03 19:02:00
【问题描述】:

该项目的目标是从表中抓取数据并将结果放入 sqllite 数据库,但是我不知道我目前尝试的方式是否可行。目前数据存储在一个列表中,由表上的每一行分隔,唯一的问题是尝试将其插入数据库。我发现此代码的错误是 sql 插入的输入不完整。 我已经尝试在线搜索解决方案,但到目前为止没有任何帮助,它会导致此问题或列表索引超出范围。

from bs4 import BeautifulSoup
import requests
import sqlite3
headers = {'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0"}
url = "https://en.wikipedia.org/wiki/Comparison_of_computer_viruses"
r = requests.get(url,headers=headers)
soup = BeautifulSoup(r.content, "html.parser")
table = soup.find_all('table')[1]
rows = table.find_all('tr')
row_list= list()
for tr in rows:
    td = tr.find_all('td')
    row = [i.text for i in td]
    row_list.append(row)
print(row_list)
print(row_list[1][1])
maldb = sqlite3.connect("maldb")
cursor = maldb.cursor()
cursor.execute('''drop table if exists mal''')
cursor.execute('''create table mal
            (virus text primary key,
            alias text,
            typeof text,
            subtype text,
            isolation_date text,
            isolation text,
            origin text,
            author text,
            notes text)
''')
for z in range(1,95):
    cursor.execute('''INSERT into mal ('?','?','?','?','?','?','?','?','?')''',(row_list[z][0],row_list[z][1],row_list[z][2],row_list[z][3],row_list[z][4],row_list[z][5],row_list[z][6],row_list[z][7],row_list[z][8]))
maldb.commit()
maldb.close()

【问题讨论】:

  • 你最好从 Postgres 文档中检查 INSERT 语法。尝试缩小问题二相关异常,最终提供实际内容。

标签: python sqlite beautifulsoup


【解决方案1】:

几件事:

  1. 语法不正确:你想要的。
  2. 您将“病毒”值设置为主键,但'Jerusalem' 在那里出现了两次。您不能有超过 1 行与主键具有相同的值。
  3. 我只会使用 pandas 来解析 html <table> 标签。
  4. 虽然您可以遍历每一行以添加它,但还有一种方法可以使用executemany() 方法一次写入多个/所有行。见here

代码:

import sqlite3
import pandas as pd

table = pd.read_html("https://en.wikipedia.org/wiki/Comparison_of_computer_viruses")[1]

maldb = sqlite3.connect("maldb.db")
cursor = maldb.cursor()
cursor.execute('''drop table if exists mal''')
cursor.execute('''create table mal
            (virus text primary key,
            alias text,
            typeof text,
            subtype text,
            isolation_date text,
            isolation text,
            origin text,
            author text,
            notes text)
''')

for idx, row in table.iterrows():
    try:
        sql = "INSERT INTO mal (virus, alias, typeof, subtype, isolation_date, isolation, origin, author, notes ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
        val = (row['Virus'],row['Alias(es)'],row['Types'],row['Subtype'],row['Isolation Date'],row['Isolation'],row['Origin'],row['Author'],row['Notes'])
        cursor.execute(sql, val)
    except Exception as e:
        print (e)
        print (val)

maldb.commit()
maldb.close()

【讨论】:

    【解决方案2】:

    这里有不同的问题。第一个是您的语法不正确:您不应引用 ? 字符,因此至少您的查询应该是:

    cursor.execute('''INSERT into mal (?,?,?,?,?,?,?,?,?)''',(row_list[z][0],row_list[z][1],row_list[z][2],row_list[z][3],row_list[z][4],row_list[z][5],row_list[z][6],row_list[z][7],row_list[z][8]))
    

    更糟糕的是,有些行没有 9 个项目(第一个没有,另一个只有 8 个),所以你应该检查一下。最后,最好使用循环executeexecutemany,因为查询只编译一次。所以我建议:

    cursor.executemany('''INSERT into mal values(?,?,?,?,?,?,?,?,?)''',
                       [row for row in row_list if len(row) == 9])
    

    最后,您不应该对virus 列使用PRIMARY KEY 属性,因为该列表实际上包含'Jerusalem\n' 的重复项,而主键必须是唯一的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      相关资源
      最近更新 更多