コンソールで CTRL+C などを使用してプログラムを停止する方法を知りたいです。問題は、プログラムに 2 つのスレッドがあることです。スレッド 1 は Web をクロールして一部のデータを抽出し、スレッド 2 はこのデータをユーザーが読み取り可能な形式で表示します。両方の部分が同じデータベースを共有します。私はこのようにそれらを実行します:
from threading import Thread
import ResultsPresenter
def runSpider():
Thread(target=initSpider).start()
Thread(target=ResultsPresenter.runPresenter).start()
if __name__ == "__main__":
runSpider()
どうやってやるの?
わかりましたので、独自のスレッドクラスを作成しました:
import threading
class MyThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(MyThread, self).__init__()
self._stop = threading.Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
では、resultPresenter とクローラーのスニペットをここに投稿します。resultPresenter のコードは次のとおりです。
# configuration
DEBUG = False
DATABASE = database.__path__[0] + '/database.db'
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_envvar('CRAWLER_SETTINGS', silent=True)
def runPresenter():
url = "http://127.0.0.1:5000"
webbrowser.open_new(url)
app.run()
ここでは省略したメソッドが 2 つあります。そのうちの 1 つはデータベースに接続し、2 番目のメソッドは html テンプレートをロードして結果を表示します。条件が満たされるか、ユーザーがプログラムを停止するまでこれを繰り返します(私が実装しようとしているもの)。他にも 2 つの方法があります。1 つはコマンド ラインからの最初のリンクを取得する方法で、もう 1 つは有効な引数です。引数が無効な場合は、crawl() メソッドを実行しません。
クローラーの短いバージョンは次のとおりです。
def crawl(initialLink, maxDepth):
#here I am setting initial values, lists etc
while not(depth >= maxDepth or len(pagesToCrawl) <= 0):
#this is the main loop that stops when certain depth is
#reached or there is nothing to crawl
#Here I am popping urls from url queue, parse them and
#insert interesting data into the database
parser.close()
sock.close()
dataManager.closeConnection()
これらのモジュールをスレッドで開始するinitファイルは次のとおりです。
import ResultsPresenter, MyThread, time, threading
def runSpider():
MyThread.MyThread(target=initSpider).start()
MyThread.MyThread(target=ResultsPresenter.runPresenter).start()
def initSpider():
import Crawler
import database.__init__
import schemas.__init__
import static.__init__
import templates.__init__
link, maxDepth = Crawler.getInitialLink()
if link:
Crawler.crawl(link, maxDepth)
killall = False
if __name__ == "__main__":
global killall
runSpider()
while True:
try:
time.sleep(1)
except:
for thread in threading.enumerate():
thread.stop()
killall = True
raise