在Python for循环中插入MySQL时出错
可能是重复的问题:
将列表转换为字符串,以便在Python Scrapy中插入到我的SQL的一行中
这个脚本写得对吗?我想把抓取到的h2、h3和meta数据直接插入到mysql数据库里。下面的代码运行得不太对。有人能给我一个解决方案吗?我觉得问题出在for循环上。
def parse(self, response):
hxs = HtmlXPathSelector(response)
sites = hxs.select('//ul/li')
items = [site.select('//h2').extract()]
item = [site.select('//h3').extract()]
item1 = [site.select('//meta').extract()]
for index,index1,index2 in range (len( items)),range(len(item)),range(len(item1)):
con = MySQLdb.connect(
host="localhost",
user="dreamriks",
passwd="dreamriks",
db="scraped_data"
)
cur = con.cursor()
str = items[index]
str1 = item[index1]
str2 = item1[index2]
cur.execute("""Insert into heads(h2,h3,meta) Values(%s,%s,%s)""",(str,str1,str2))
con.commit()
con.close()
出现的错误是:
for index,index1,index2 in range (len( items)),range(len(item)),range(len(item1)):
exceptions.ValueError: need more than 1 value to unpack
2 个回答
0
我只是想确认一下——你确定这是你想要做的事情吗?
这个命令
for x, y, z in l1, l2, l3
会依次返回每个列表中的第一个元素,然后是第二个,以此类推。更好的做法是使用itertools库,特别是izip。
from itertools import izip
for x, y, z in izip(l1, l2, l3)
这个方法在逻辑上是等价的,但效率更高(因为izip是一个生成器)。
不过,看起来你想要做的是按顺序索引每个列表中的元素,所以你的代码中有很多多余的部分,而且如果列表长度不一样的话会出错。作为初步尝试,我会做一些逻辑上等价的事情,比如这样。它会因为同样的原因在断言时出错,但应该会更清晰。
from itertools import izip
import traceback
def parse(self, response):
hxs = HtmlXPathSelector(response)
# get the data however you got it (not sure exactly what the goal is here)
sites = hxs.select('//ul/li')
items = [site.select('//h2').extract()]
item = [site.select('//h3').extract()]
item1 = [site.select('//meta').extract()]
# open a connection to the server
con = MySQLdb.connect(
host="localhost",
user="dreamriks",
passwd="dreamriks",
db="scraped_data",
)
cur = con.cursor()
# run the commands:
try:
for st, st1, st2 in izip(items, item, item1):
assert st and st1 and st2, 'one of the three values is missing. strings were: (%s, %s, %s)' % (st, st1, st2)
cur.execute("Insert into heads(h2, h3, meta) Values(%s, %s, %s)" % (st, st1, st2))
con.commit()
except:
#if there is a failure, print the error and die
traceback.print_stack()
finally:
#no matter what happens, close the connection to the server
con.close()
2
看起来你有一个列表里面只有一个元素,这可能就是问题所在。请检查一下所有的列表:
items = [site.select('//h2').extract()]
item = [site.select('//h3').extract()]
item1 = [site.select('//meta').extract()]
确保它们的内容是你预期的。
for index,index1,index2 in range (len( items)),range(len(item)),range(len(item1))
这个语法是同时遍历所有的列表,如果任何一个列表的长度不一致,就会出现值错误。
为了更好地理解你的问题,请看下面的内容:
In [1]: l1 = [1,2,3]
In [2]: l2 = [4,5,6]
In [3]: l3 = [7]
In [4]: for index,index1,index2 in range (len( l1)),range(len(l2)),range(len(l3)):
....: print "Hi"
....:
....:
Hi
Hi
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/home/avasal/<ipython console> in <module>()
ValueError: need more than 1 value to unpack
如果可以的话,你能试试这个吗:
for index,index1,index2 in zip(range (len( items)),range(len(item)),range(len(item1)))