パイプラインにスクレイプされたアイテムのリストを作成し、そのリストのサイズがNより大きい場合は、DB関数を呼び出してデータを保存します。私のプロジェクトの100%作業用コードです。 close_spider()
を参照してください。スパイダーが閉鎖された時点で、self.items
にはN個未満のアイテムがある可能性がありますので、self.items
の残りのデータもスパイダーが閉じられるとDBに保存されます。
from scrapy import signals
class YourPipeline(object):
def __init__(self):
self.items = []
def process_item(self, item, spider):
self.items.extend([ item ])
if len(self.items) >= 50:
self.insert_current_items(spider)
return item
def insert_current_items(self, spider):
for item in self.items:
update_query = ', '.join(["`" + key + "` = %s " for key, value in item.iteritems()])
query = "SELECT asin FROM " + spider.tbl_name + " WHERE asin = %s LIMIT 1"
spider.cursor.execute(query, (item['asin']))
existing = spider.cursor.fetchone()
if spider.cursor.rowcount > 0:
query = "UPDATE " + spider.tbl_name + " SET " + update_query + ", date_update = CURRENT_TIMESTAMP WHERE asin = %s"
update_query_vals = list(item.values())
update_query_vals.extend([existing['YOUR_UNIQUE_COLUMN']])
try:
spider.cursor.execute(query, update_query_vals)
except Exception as e:
if 'MySQL server has gone away' in str(e):
spider.connectDB()
spider.cursor.execute(query, update_query_vals)
else:
raise e
else:
# This ELSE is likely never to get executed because we are not scraping ASINS from Amazon website, we just import ASINs into DB from another script
try:
placeholders = ', '.join(['%s'] * len(item))
columns = ', '.join(item.keys())
query = "INSERT INTO %s (%s) VALUES (%s)" % (spider.tbl_name, columns, placeholders)
spider.cursor.execute(query, item)
except Exception as e:
if 'MySQL server has gone away' in str(e):
spider.connectDB()
spider.cursor.execute(query, item)
else:
raise e
self.items = []
def close_spider(self, spider):
self.insert_current_items(spider)
つまり、多くの同時リクエストもあります。それらのすべてがself.itemsのサイズを1ずつ増やします。そのサイズが50になると、最も近いprocess_itemリフレッシュ・リストが表示されます。しかし、insert_current_itemsがまだ実行中で、他の50項目がself.itemsで収集され、次に他のものが収集される場合はどうなりますか?ですから、同時に動作するinsert_current_itemsメソッドがいくつかありますか? – user2572790
'self.items'はグローバル変数ですので、何度も同時にprocess_itemメソッドが呼び出されても、問題はありません – Umair
はい、spider.cursor.execute(query、update_query_vals)メソッドの問題を意味します。それは同時に何度も働く? – user2572790