将python string / unicode对象传递给sqlite

时间:2014-05-21 18:14:32

标签: python unicode sqlite scrapy

我已经陷入了Python和sqlite之间的unicode地狱。我试图做一些我认为很简单的事情:

1)用scrapy ==>刮掉一个网站2)用lxml ==>提取主要文本内容。 3)将文本传递到SQLite数据库。

前两个步骤很简单,使用以下代码:

class OpEdSpider(BaseSpider):
  name = "opeds"
  allowed_domains = ["scrapy.org"]
  start_urls = ["http://doc.scrapy.org/en/latest/intro/tutorial.html"]

  def parse(self, response):
    data = response.body
    into_lxml = html.fromstring(data)
    raw_content = unicode(into_lxml.text_content())
    print raw_content

第一部分使用Python的scrapy库来抓取网站;解析函数通过lxml的text_content()属性提取相当干净的文本(我对精确的html / xml结构不感兴趣;这个函数给我的是足够干净的文本用于分析道路)。使用或不使用raw_content打印unicode()会显示我想要的内容,格式化为我想要的格式。正如预期的那样,type(raw_content)分别是lxml.etree._*unicode

当我尝试将raw_content添加到SQLite数据库时,事情就崩溃了,用这个函数替换了print函数:

class OpEdSpider(BaseSpider):
  name = "opeds"
  allowed_domains = ["scrapy.org"]
  start_urls = ["http://doc.scrapy.org/en/latest/intro/tutorial.html"]

  def parse(self, response):
    data = response.body
    into_lxml = html.fromstring(data)
    raw_content = unicode(into_lxml.text_content(),)
    add_to_db(raw_content)

def add_to_db(item):
  conn = sqlite3.connect('testproject_tracker.db')
  c = conn.cursor()

  c.execute('''CREATE TABLE if not exists tracker
            (web_content TEXT)''')

  c.execute("INSERT INTO tracker VALUES (?)", (item,))

  conn.commit()

  for row in c.execute('SELECT * from tracker'):
    print row

  conn.close()

以前从raw_content完全清理过的输出看起来很糟糕(这里是一个小样本):

  

\ n \'示例标题\' \ n \ n \ n \ n \ n \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

在这里,我迷失了方向。 raw_content是一个unicode文本对象; SQLite列(web_content)应该接受unicode。然而在某个地方,raw_content被编码/解码到上面的混乱中。

我已经研究过这个问题,我认为我明白了问题所在但不是解决方案(但如果我错了,请纠正我)。 raw_content作为元组传递给sqlite *,这可能会将raw_content变量中的非结构化文本分解为元组的单独元素(可能是行?),然后由\n和其他字符串分隔出来在数据库中。我怎么能避免这种情况?是否可以将raw_content原样传递给SQLite;即,准确地将打印raw_content显示的内容传递到数据库中,然后将其传递到数据库中?

为冗长的问题道歉。我试图平衡简洁性和足够的细节,以免让别人复制我尝试过的失败的解决方案。

[*如果我没有将raw_content作为元组传递(如果我删除尾随的,),则会收到以下错误:

  

sqlite3.ProgrammingError:提供的绑定数量不正确。当前语句使用1,并且提供了25741。

1 个答案:

答案 0 :(得分:0)

尝试print row[0]

我认为它实际上很好...行是一个列表,所以你看到字符串的repr而不是字符串本身

>>> x = ["hello\nworld"] #essentially equivelent to your row variable
>>> print x
['hello\nworld'] #this is likely simillar to what you are seeing
>>> print x[0] #when you want to see this
hello
world

我猜...(例如,我不认为它的编码/解码任何东西,它只是保存原始字节...但是select语句返回一个列表...打印列表打印列表中的项目的repr,而不是打印实际列表)