如何运行脚本一分钟,停止执行,然后再次启动?

时间:2018-08-25 15:12:46

标签: python service packet-capture

我当前正在处理一个要运行特定时间(例如一分钟)的脚本,然后必须停止执行5秒钟,然后再次开始执行(此循环一直持续重复),没有失败。该脚本在Python 3.x中运行,可在Ubuntu环境中运行。因此,创建相同的Service / Daemon也将起作用(尽管脚本的执行必须停止几秒钟)。

它基本上是在捕获实时数据时使用Scapy模块进行数据包嗅探,然后在将数据插入数据库之前对这些捕获的数据包进行一些分析。当我通过按Ctrl+C停止执行脚本时,它将停止,然后将数据插入DB中,而不是并行插入。虽然最好是并行执行此过程,并且脚本永远不必停止执行,但在此之前,我需要一种解决方法。

我的方法:

import scapy

def main():
    capture = LiveCapture(interface = "<some interface>", filter="<some filter>")
    count = 0
    for pkt in capture:
        #DO SOMETHING

        insert_in_DB()   #--------This happens only when I stop the execution.
        if count == 100:
            count = 0
            #back to main()

所以,你          大致了解我的代码正在尝试做什么,对吗?但是我希望这种情况每隔1分钟发生一次,在运行1分钟后,代码执行将停止,以便可以将数据输入到DB中,然后在5秒或更短的时间内重新开始。

预先感谢:)

1 个答案:

答案 0 :(得分:1)

您必须使用 MySQLdb 在python中使用MySQL,并需要Twisted adbapi来执行异步连接。

MySQLdb:

sudo apt-get install python-dev
sudo apt-get install libmysqlclient-dev
pip3 install mysql-python

扭曲的adbapi:

pip3 install twisted

Spider.py

def parse(self, response):
    yield {
        'item_id' : ...
        'item_name': ...
        ...
    }

MySQLStorePipeline添加到pipelines.py并在settings.py中声明:

pipelines.py

from twisted.enterprise import adbapi       #pip3 install twisted
from scrapy import log
from scrapy.conf import settings
import MySQLdb.cursors

class MySQLStorePipeline(object):
    #A pipeline to store the item in a MySQL database.
    #This implementation uses Twisted's asynchronous database API.


    def __init__(self):
        dbargs = settings.get('DB_CONN')
        self.dbpool = adbapi.ConnectionPool(
            "MySQLdb",
            cursorclass=MySQLdb.cursors.DictCursor,
            **dbargs
        )

    def process_item(self, item, spider):
        # run db query in thread pool
        query = self.dbpool.runInteraction(self._conditional_insert, item)
        query.addErrback(self.handle_error)
        return item

    def _conditional_insert(self, tx, item):
        # create record if doesn't exist. 
        # all this block run on it's own thread
        item_id = item['item_id']
        db_table = 'your_table_name'

        try:
            tx.execute("SELECT 1 FROM " + db_table + " WHERE item_id = %s", (item_id, ))
        except:
            print("## Query Failed:" + str(tx._last_executed))

        result = tx.fetchone()

        if result:
            log.msg("Item already stored in db: %s" % item, level=log.DEBUG)
        else:
            try:
                tx.execute(\
                    "INSERT INTO " + db_table + " (item_id, item_name) "
                    "values (%s, %s)",
                    (item_id, item['item_name'])
                )
                log.msg("Item stored in db: %s" % item, level=log.DEBUG)
            except:
                print("## Query Failed:" + str(tx._last_executed))

    def handle_error(self, e):
        log.err(e)

Settings.py

ITEM_PIPELINES = {
    'your_project.pipelines.your_projectPipeline': 300,
    'your_project.pipelines.MySQLStorePipeline': 600,
} #note: https://stackoverflow.com/questions/37442907/scrapy-attributeerror-list-object-has-no-attribute-iteritems

DB_CONN = {    
    'db': 'your_db',
    'user': 'your_username',
    'passwd': 'your_password',
    'host': 'your_host',
    'charset': 'utf8',
    'use_unicode': True,
} 

注释

用您的SQL凭据替换所有your _ *****。

上面的代码假定您的SQL表只有两列:'item_id','item_name',当然,您可以在INSERT INTO查询中对其进行修改。

如果您有任何问题,请发表评论。