Очень новичок в питоне. Я пытаюсь получить данные из RSS-канала, проанализировать данные и затем вставить данные в базу данных. Мой короткий фрагмент кода получает правильные элементы, и я могу распечатать результаты, но я могу получить только последний элемент в RSS-канале для публикации в базе данных. Я считаю, что неправильно определил «html» и «ссылка». Я хочу, чтобы item.title и item.link заполнили список, который затем будет введен в базу данных в правильном порядке. Любая помощь высоко ценится.
import sys
import requests
import urllib2
import feedparser
import psycopg2
import psycopg2.extras
from psycopg2.extras import execute_values
import time
url = "https://www.ferc.gov/xml/whats-new.xml"
response = urllib2.urlopen(url).read()
#saving the xml file
response = requests.get(url)
#with open('whats_hot.xml', 'wb') as file:
# file.write(response.content)
d = feedparser.parse('https://www.ferc.gov/xml/whats-new.xml')
for item in d.entries:
print "------"
print item.published
print item.title
print item.link
html = item.published + item.title
link = item.link
con = psycopg2.connect(database = "xx",
user = "xx", password = "xx", host = "127.0.0.1",
port = "5432")
print("Database opened successfully")
cur = con.cursor()
#try:
psycopg2.extras.execute_values(cur,
"insert into ferc_hots (link,html) values %s",
[(link,html)])
#except psycopg2.IntegrityError:
# print 'Duplicate values found. Insert was not successful'
con.commit()
print("Records inserted successfully")
con.close()
Ваш оператор вставки также должен находиться внутри цикла for. В противном случае вы вставляете только последнюю запись.
con = psycopg2.connect(database = "xx",
user = "xx", password = "xx", host = "127.0.0.1",
port = "5432")
print("Database opened successfully")
cur = con.cursor()
for item in d.entries:
print "------"
print item.published
print item.title
print item.link
html = item.published + item.title
link = item.link
psycopg2.extras.execute_values(cur,"insert into ferc_hots (link,html) values %s",[(link,html)])
con.commit()
print("Records inserted successfully")
con.close()
Другой вариант — сохранить список записей и вставить их вместе в конце.
Список аргументов для execute_values
должен быть «последовательностью последовательностей». Который представляет собой список списков (или список кортежей). В вашем случае вы оставляете только окончательные значения элементов в html
и link
и поэтому предоставляете только один элемент.
Вам понадобится что-то вроде этого:
args = []
for item in d.entries:
print "------"
print item.published
print item.title
print item.link
args.append([item.published + item.title, item.link])
Или одним махом:
args = [[item.published + item.title, item.link] for item in d.entries]
Тогда вставка выглядит примерно так:
psycopg2.extras.execute_values(cur,
"insert into ferc_hots (link,html) values %s",
args)
Спасибо за Ваш ответ. Я думаю, что вариант одним махом - это понимание списка?
Правильный. Очень "питоновский", но требует некоторого привыкания.
html и ссылка — это просто однострочные значения. Они продолжают меняться в вашем цикле, но к тому времени, когда вы переходите к вставке, им просто задано последнее значение. Вам нужно сохранить список кортежей значений, которые будут переданы в вашу вставку. Обратите внимание на двойные круглые скобки, потому что кортеж добавляется к списку значений. Кортеж определяется как (элемент, элемент), поэтому вы добавляете (элемент, элемент), а не просто элемент.
values = []
for item in d.entries:
print "------"
print item.published
print item.title
print item.link
values.append((item.link, item.published + item.title))
...
psycopg2.extras.execute_values(cur,
"insert into ferc_hots (link,html) values %s",
values)
Это сработало! Первоначально я сделал два пустых списка, а затем добавил в них элементы. Затем я попытался вставить их в базу данных, но у меня возникли проблемы с синтаксисом. Работает ли создание одного списка, потому что тогда добавление добавляет два значения, разделенные запятыми? Итак, когда команда вставки перечисляет две записи таблицы, список заполняет таблицу соответствующими значениями?
функция execute_values ищет список кортежей. Элементы кортежей должны быть упорядочены, как вставка. Поэтому вставка в значения table1 (colA, colB) %s должна иметь список кортежей, таких как (ColAValue, ColBValue), вы можете иметь столько значений в кортеже, они просто должны соответствовать оператору вставки. Затем модуль psycopg2 проверяет, чтобы они оказались в правильном формате значений (ColAValue, ColBValue).
link
иhtml
переопределяются каждый раз, когда вы проходите цикл. Вы выполняете вставку только после завершения цикла, поэтому для вставки будут использоваться последние значенияlink
иhtml
. Сколько ссылок вы обычно вставляете? Кроме того, если вы хотите заполнить список, почему вы не добавляетеhtml
иlink
к списку? Что касается самой вставки, посмотрите этот вопрос.