在Python for循环中插入MySQL时出错

-1 投票
2 回答
1043 浏览
提问于 2025-04-17 12:00

可能是重复的问题:
将列表转换为字符串,以便在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)))

撰写回答