我当前正在处理一个要运行特定时间(例如一分钟)的脚本,然后必须停止执行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秒或更短的时间内重新开始。
预先感谢:)
答案 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查询中对其进行修改。
如果您有任何问题,请发表评论。