MySQLdb 和 Scrapy:INSERT INTO 错误
我正在尝试使用 Scrapy 和 MySQLdb 的 INSERT INTO 命令,把抓取到的数据放入本地的 MySQL 数据库里。我已经花了好几天在研究这个,但还没有找到解决办法。我希望有人能帮我理解我哪里做错了,因为我对 Python 还很陌生。
这是 spider.py 的内容:
from scrapy.selector import Selector
from scrapy.contrib.spiders import CrawlSpider
from scrapy.log import *
from folketing_crawler.settings import *
from folketing_crawler.items import FolketingCrawlerItem
class FolketingSpider(CrawlSpider):
name = 'ft2'
allowed_domains = ["ft.dk"]
start_urls = ["http://www.ft.dk/Dokumenter/Vis_efter_type/Beslutningsforslag.aspx?session=&caseStatus=-1&ministerArea=-1&committee=&proposedBy=1&startDate=20110915&endDate=20140421&dateRelatedActivity=100242%2f200049&sortColumn=&sortOrder=&startRecord=&totalNumberOfRecords=&numberOfRecords=999&pageNr=#dok"]
def parse(self, response):
sel = Selector(response)
item = FolketingCrawlerItem()
item['nr'] = sel.xpath('/html/body/form/div[3]/div/div[2]/div[5]/div/div/table/tbody/tr/td[1]/text()').extract()
return item
这是 pipelines.py 的内容:
import sys
import MySQLdb
import MySQLdb.cursors
import hashlib
from scrapy.exceptions import DropItem
from scrapy.http import Request
from scrapy.item import Item, Field
class FolketingCrawlerPipeline(object):
def process_item(self, item, spider):
db = MySQLdb.connect(user='root', passwd='password', db='ftdb', host='localhost', charset="utf8", use_unicode=True)
cursor = db.cursor()
cursor.execute("INSERT INTO employees (hire_date) VALUES (%s)", item['nr'])
db.commit()
print "INSERT was successful"
return item
这是 items.py 的内容:
from scrapy.item import Item, Field
class FolketingCrawlerItem(Item):
nr = Field()
在 settings.py 中,我添加了这些内容来调用管道:
ITEM_PIPELINES = {
'folketing_crawler.pipelines.FolketingCrawlerPipeline': 500
}
看起来 pipeline.py 中的 "cursor.execute" 有问题,但我在网上找了各种不同的写法来尝试,包括:
cursor.execute("INSERT INTO employees (hire_date) VALUES (%s)", item['nr'])
cursor.execute("""INSERT INTO employees (hire_date) VALUES (%s)""", item['nr'])
cursor.execute("INSERT INTO employees (hire_date) VALUES (%s)", (item['nr']))
cursor.execute("INSERT INTO employees (hire_date,) VALUES (%s,)", (item['nr'],))
cursor.execute("INSERT INTO employees (hire_date) VALUES (%s)", str(item['nr'])
我尝试了所有可能的组合,但也许问题出在 spider 里,数据存储在 item['nr'] 里?当我运行这个 scrapy 项目时,收到了以下错误:
exceptions.TypeError: not all arguments converted during string formatting
希望有人能帮我解决这个问题。我需要把数据列表存储在一行里,这样每一“条”数据都能在表格的新行中。
提前谢谢大家。
3 个回答
0
hire_date
看起来像是一个 SQL 时间戳。你可以给它一个 Python 的 datetime
对象,像这样:
cursor.execute("INSERT INTO employees (hire_date) VALUES (?)", (datetime.datetime.now(),) )
注意:execute
方法总是需要一个参数,通常是一个元组。参考链接:https://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.execute
0
我觉得
item['nr'] = sel.xpath('/html/body/form/div[3]/div/div[2]/div[5]/div/div/table/tbody/tr/td[1]/text()').extract()
返回一个元组,你试过直接获取第一个元素吗?
item['nr'] = sel.xpath('/html/body/form/div[3]/div/div[2]/div[5]/div/div/table/tbody/tr/td[1]/text()').extract()[0]
0
在 scrapy shell 会话中检查时,
$ scrapy shell "http://www.ft.dk/Dokumenter/Vis_efter_type/Beslutningsforslag.aspx?session=&caseStatus=-1&ministerArea=-1&committee=&proposedBy=1&startDate=20110915&endDate=20140421&dateRelatedActivity=100242%2f200049&sortColumn=&sortOrder=&startRecord=&totalNumberOfRecords=&numberOfRecords=999&pageNr=#dok"
2014-07-01 01:29:28+0200 [scrapy] INFO: Scrapy 0.24.1 started (bot: scrapybot)
...
sel.xpath('/html/body/form/div[3]/div/div[2]/div[5]/div/div/table/tbody/tr/td[1]/text()').extract()
Out[1]:
[u'B 2',
u'B 3',
u'B 4',
u'B 5',
u'B 6',
...
u'B 88',
u'B 89',
u'B 90',
u'B 91',
u'B 92',
u'B 93']
In [2]:
如果你想把上面列表中的每个元素都存储为一行,可能应该使用类似下面的方式:
cursor.executemany("INSERT INTO employees (hire_date) VALUES (%s)",
[(nr,) for nr in item['nr']])