首页 > 解决方案 > 如果语句仅在 Scrapy 中将新值写入 PostgreSQL 数据库

问题描述

我有一个 Scrapy 蜘蛛,它使用 psycopg2 将抓取的数据写入 PostgreSQL 数据库。我有 Scrapyd 运行和项目导出器,一切都设置得很好。我正在抓取 craigslist 的劳动部分以获取帖子 url、标题和创建日期。我想在新帖子上创建通知,为了实现这一点,我将 PostgreSQL 数据库中的 url 字段设为主键。

我尝试的第一件事是一个 try 块(它在我使用 requests 和 BeautifulSoup 运行的刮板中工作。

        try:
            cur.execute( 'INSERT INTO postgres.public.clist (title, url, created, time) VALUES (%s, %s, %s, %s)', (title, url, pdate, pdate))
            print('notification')
        except:
            pass
        finally:
            conn.commit()

Scrapy 引擎似乎从不抛出异常,因为它总是尝试访问INSERT INTO数据库。蜘蛛的第二遍会从 psycopg2 抛出一堆错误,因为 url 字段不是唯一的。

psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "clist_url_uindex"
DETAIL:  Key (url)=(https://delaware.craigslist.org/lbg/d/wilmington-truck-cargo-vans-owners-make/6959980210.html) already exists.

接下来我尝试了

def process_item(self, item, spider):

    cdate = datetime.strptime(item['dtime'][0], '%Y-%m-%d %H:%M')
    item_title = item['title'][0]
    item_url = item['url'][0]
    query = 'select * from postgres.public.clist where url = %s'
    self.cur.execute(query, (item_url, ))
    results = self.cur.rowcount
    if results is not 0:
       self.cur.execute( "insert into postgres.public.clist(title, url, created, time) values(%s,%s, %s, %s)", (item_title, item_url, cdate, cdate) )
    else:
       pass
    self.connection.commit()

它仍然尝试写入每条记录,并且我收到一个错误,因为 url 字段不是唯一的。

我不明白为什么这些都不起作用,尤其是try在 Scrapy 环境之外工作的块。

我什至在 middlewares.py 文件中看到了 process_spider_exception,它已经pass在其中了。

有人可以为我指出为什么这不起作用的正确方向吗?

标签: pythonpostgresqlscrapypsycopg2scrapyd

解决方案


您的代码显示“查找此 url 在数据库中存在的次数。如果该数字不为零,则插入 url,否则不执行任何操作”。

逻辑颠倒了。如果计数 = 0,您只想进行插入。

在旁注中,您应该查看ON DUPLICATE KEY UPDATE.


推荐阅读