[英]When a new file arrives in S3, trigger luigi task
我有一個帶有新對象的存儲桶,其中會根據它們的創建時間隨機添加鍵。 例如:
's3://my-bucket/mass/%s/%s/%s/%s/%s_%s.csv' % (time.strftime('%Y'), time.strftime('%m'), time.strftime('%d'), time.strftime('%H'), name, the_time)
實際上,這些是Scrapy爬網的輸出。 我想觸發一個將這些爬網與我擁有的主.csv產品目錄文件(稱為“ product_catalog.csv”)匹配的任務,該文件也會定期更新。
現在,我有一些用全局變量編寫的Python腳本,每次運行此過程時都會填寫這些變量。 這些需要成為導入的屬性。
所以這是需要發生的事情:
1)新的csv文件會根據抓取完成的時間顯示在“ s3:// my-bucket / mass / ...”中,並具有唯一的鍵名稱。 路易吉(Luigi)看到了這一點,開始了。
2)luigi在新文件上運行“ cleaning.py”,因此需要在運行時向其提供“ cleaning.py”(在S3中顯示的文件)參數。 除了傳遞到下一步之外,結果還保存在S3中。
3)從數據庫中獲取“ product_catalog.csv”的最新版本,並使用“ matching.py”中的“ cleaning.py”結果
我意識到這可能並不完整。 我將根據需要提供編輯內容,以使其更加清晰。
編輯
根據最初的答案,我將其配置為拉操作,從而節省了執行過程中的步驟。 但是現在我很迷茫。 應該注意的是,這是我第一次將Python項目綁定在一起,因此我在學習諸如init .py之類的東西時會學習到。 與往常一樣,成功是一條坎from的激動之路,緊接着又是下一個障礙。
這是我的問題:
1)我不清楚如何從Scrapy導入蜘蛛。 我大約有十二個,目標是讓luigi管理所有這些對象的crawl> clean> match的過程。 Scrapy文檔說包括:
class MySpider(scrapy.Spider):
# Your spider definition
這意味着什么? 在控制蜘蛛的腳本中重新編寫蜘蛛? 那沒有道理,他們的例子也無濟於事。
2)我已經配置了Scrapy管道以導出到S3,但是luigi似乎也可以通過output()來做到這一點。 我應該使用哪個?如何使它們一起玩?
3)Luigi說CrawlTask()成功運行了,但是這是錯誤的,因為它可以在幾秒鍾內完成,並且爬網通常需要幾分鍾。 也沒有對應於成功的輸出文件。
4)我在哪里提供S3的憑據?
這是我的代碼。 我已經注釋掉了無法代替我認為更好的東西。 但是我的感覺是,我想做的事情有一個宏偉的架構,我只是還不了解。
import luigi
from luigi.s3 import S3Target, S3Client
import my_matching
from datetime import datetime
import os
import scrapy
from twisted.internet import reactor
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from my_crawlers.my_crawlers.spiders import my_spider
class CrawlTask(luigi.Task):
crawltime = datetime.now()
spider = luigi.Parameter()
#vertical = luigi.Parameter()
def requires(self):
pass
def output(self):
return luigi.LocalTarget("actual_data_staging/crawl_luigi_test_{}.csv".format(self.crawltime))
#return S3Target("s3://my-bucket/mass/crawl_luigi_test_{}.csv".format(self.crawltime))
def run(self):
os.system("scrapy crawl %s" % self.spider)
#process = CrawlerProcess(get_project_settings())
#process.crawl("%s" % self.spider)
#process.start()
class FetchPC(luigi.Task):
vertical = luigi.Parameter()
def output(self):
if self.vertical == "product1":
return "actual_data_staging/product1_catalog.csv"
elif self.vertical == "product2":
return "actual_data_staging/product2_catalog.csv"
class MatchTask(luigi.Task):
crawltime = CrawlTask.crawltime
vertical = luigi.Parameter()
spider = luigi.Parameter()
def requires(self):
return CrawlTask(spider=self.spider)
return FetchPC(vertical=self.vertical)
def output(self):
return luigi.LocalTarget("actual_data_staging/crawl_luigi_test_matched_{}.csv".format(self.crawltime))
#return S3Target("s3://my-bucket/mass/crawl_luigi_test_matched_{}.csv".format(CrawlTask.crawltime))
def run(self):
if self.vertical == 'product1':
switch_board(requires.CrawlTask(), requires.FetchPC())
MatchTask指的是我編寫的Python腳本,該腳本將報廢的產品與我的產品目錄進行比較。 看起來像這樣:
def create_search(value):
...
def clean_column(column):
...
def color_false_positive():
...
def switch_board(scrape, product_catalog):
# this function coordinates the whole script
下面是它看起來的非常粗略的輪廓。 我認為與luigi作為拉動系統的工作方式之間的主要區別在於,您首先指定所需的輸出,然后觸發該輸出所依賴的其他任務。 因此,與其在爬網結束時命名事物,不如以一開始就知道的東西來命名事物。 可以用另一種方式來做,只是很多不必要的復雜性。
class CrawlTask(luigi.Task):
crawltime = luigi.DateParameter()
def requires(self):
pass
def get_filename(self):
return "s3://my-bucket/crawl_{}.csv".format(self.crawltime)
def output(self):
return S3Target(self.get_filename())
def run(self):
perform_crawl(s3_filename=self.get_filename())
class CleanTask(luigi.Task):
crawltime = luigi.DateParameter()
def requires(self):
return CrawlTask(crawltime=self.crawltime)
def get_filename(self):
return "s3://my-bucket/clean_crawl_{}.csv".format(self.crawltime)
def output(self):
return S3Target(self.get_filename())
def run(self):
perform_clean(input_file=self.input().path, output_filename=self.get_filename())
class MatchTask(luigi.Task):
crawltime = luigi.DateParameter()
def requires(self):
return CleanTask(crawltime=self.crawltime)
def output(self):
return ##?? whatever output of this task is
def run(self):
perform_match(input_file=self.input().path)
您可以做的是創建一個同時包含爬網和處理功能的大型系統。 這樣,您就不必檢查s3中是否有新對象。 我以前沒有使用過luigi,但是也許您可以將您的拼湊工作變成一項任務,完成后再執行您的處理任務。 無論如何,我認為“檢查” s3中的新內容不是一個好主意,因為1.您將不得不使用大量API調用,並且2.您將需要編寫一堆代碼來檢查是否有“新內容”還是不可以,這可能會變得毛茸茸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.