从python for循环插入mysql时出错

时间:2012-01-31 06:37:36

标签: python mysql loops for-loop

  

可能重复:
  convert list to string to insert into my sql in one row in python scrapy

这个脚本是否正确。我想将已删除的h2,h3,元数据直接插入到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 :(得分: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)))

答案 1 :(得分: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是generator

然而,看起来你想要的是按顺序索引每个列表的元素,因此代码中会有很多开销,如果列表的长度不同,它会中断。作为第一关,我会做一些逻辑上相同的事情。由于同样的原因,它会破坏断言,但它应该更清楚。

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()