【问题标题】:Premature end of loop循环过早结束
【发布时间】:2013-07-26 10:10:06
【问题描述】:

以下是我的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sqlite3
import lxml.cssselect
import lxml.html
import xml.etree.ElementTree as etree
import urllib

db = sqlite3.connect('abiturient.sqlite')
sql = db.cursor()

query = "DELETE FROM universities"
sql.execute(query)

regions = sql.execute('SELECT * FROM regions')
for region in regions:
    doc = lxml.html.document_fromstring(urllib.urlopen(region[2]).read())

    for topic in doc.xpath('//span[@id="branch2"]/a'):
        name = topic.text_content().replace("'", "''")
        link = 'http://vstup.info/2013' + topic.attrib['href'][1:-5] + 'b.html'
        region_id = str(region[0])

        sql.execute("INSERT INTO universities (id, name, link, region_id) VALUES (NULL, '" + name + "', '" + link + "', '" + region_id + "')")

    print region[1] + ': added.'

db.commit()
db.close()

我的表regions 包含三个条目(三个用于解析的链接)。我从 SQLite 中选择它们并使用 lxml 解析它们。但是有一个问题:循环for region in regions: 只执行一次(仅解析第一个链接并停止而没有错误)。我不知道发生这种情况的原因。可能是因为循环中有一个循环?

【问题讨论】:

  • 您确定区域中有三个条目吗?如果您在执行后尝试 fetchall 怎么办:regions = sql.execute('Select...').fetchall()
  • 不完全相关,但是:TRUNCATE universities 通常比 DELETE FROM universities 好。此外,您INSERT 通过创建一个长 SQL 字符串,很容易受到注入攻击。构建字符串时使用? 或 conn.escape(x)。
  • 谢谢! fetchall() 帮助了我! :)
  • 不,这无关。只是最佳实践。
  • TRUNCATE universities 产生语法错误。也许TRUNCATE 在 SQLite 中不存在?

标签: python sqlite parsing lxml


【解决方案1】:

对于你们这些人 - 像我一样 - 聚会迟到,问题出在声明中:

regions = sql.execute('SELECT * FROM regions')

您从执行调用返回的结果是您用来进行调用的游标。 正如 Rapolas K 建议的那样,答案是使用该游标实际获取记录 - 例如:

regions = sql.execute('SELECT * FROM regions').fetchall()

或:

sql.execute('SELECT * FROM regions')
regions = sql.fetchall()

【讨论】:

  • .fetchall() is over kill - sqlite3 支持使用for row in db.execute('some query'),其中数据库连接对象的execute 产生一个可迭代的...
  • 一个很好的观点,而且更干净。你可以知道我用了多少 sqlite3。 :-)
猜你喜欢
  • 2011-12-05
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多