Python3檢測Linux上存在的scrapy進程,如果爬蟲運行完成則結束掉

場景:

在Linux上運行了很多scrapy爬蟲,採用了scrapy-redis方式爬取,爬蟲個數多了以後內存佔用太高,所以很有必要寫個py腳本自動檢測哪些爬蟲已經爬取結束了,如果爬取結束了則停止掉該進程。

scrapy-redis方式的爬蟲,怎麼判斷爬蟲已經結束了呢,我的經驗是判斷redis裡面是否還存在 爬蟲名稱 + ':requests' 這樣的鍵,沒有了則就是跑完了


Python3檢測Linux上存在的scrapy進程,如果爬蟲運行完成則結束掉

下面開始上代碼:

# coding: utf-8
# !/usr/bin/python3
import datetime
import logging
import os
import signal
import sys
import redis

today = datetime.date.today().strftime("%Y-%m-%d")
logging.basicConfig(level=logging.DEBUG,
filename=os.path.join(os.getcwd(), 'monitor_scrapys_' + today + '.txt'),
# 模式,有w和a,w就是寫模式,每次都會重新寫日誌,覆蓋之前的日誌
filemode='a',
# 日誌格式
format= '%(process)d %(asctime)s %(filename)s %(funcName)s [line:%(lineno)d] %(levelname)s %(message)s'
)


class MonitorScrapys():
def __init__(self):
self.redis_client_requests = redis.StrictRedis(host='192.168.0.2', port=6379,
db=0,
password='redispassword',
decode_responses=True)

# 獲取爬蟲有哪些,返回一個字典key是爬蟲名稱,value是進程號
def get_spider_names(self) -> dict:
spider_names = {}
out = os.popen("ps aux | grep scrapy").read()
for line in out.splitlines():
spider_name = line.split('crawl')[1].replace(' ', '')
# print("spider_name:{spider_name}".format(spider_name=spider_name))
pid = int(line.split()[1])
spider_names.update({spider_name: pid})
return spider_names

# 檢測爬蟲是否已經跑完了
def check_spider_has_requests(self, spider_name: str) -> bool:

requests_key = spider_name + ':requests'
# 如果redis裡面沒有 爬蟲名稱 + ':requests' 這樣的鍵,沒有了則就是跑完了
return self.redis_client_requests.exists(requests_key)

# 獲取進程號的另一種方式
def get_spider_process(self, spider_name: str) -> int:
get_pid_command = "ps -ef | grep 'crawl " + spider_name + "' | grep -v grep | awk '{ print $2 }'"
pid = os.popen(get_pid_command).read()
return pid

# 殺掉進程
def kill_exception_spider_by_pid(self, pid: int) -> None:
# 一種方式是shell的方式
# kill_command = "kill -9 {0}".format(pid)
# os.system(kill_command)
# 另一種方式
os.kill(pid, signal.SIGKILL)


if __name__ == '__main__':
monitor_scrapys = MonitorScrapys()
# 獲取存在哪些爬蟲
spider_names = monitor_scrapys.get_spider_names()
logging.info(spider_names)
for key, value in spider_names.items():
spider_name = key
pid = value
if monitor_scrapys.check_spider_has_requests(spider_name):
logging.info("{0} 的進程{1}還存在 requests還存在,說明還在跑".format(spider_name, pid))
else:
monitor_scrapys.kill_exception_spider_by_pid(pid)
logging.info("{0} requests不存在 進程被殺掉了".format(spider_name))
logging.info("結束啦!!!")
sys.exit(0)

在Linux服務器上設置個定時器運行這個py文件即可,很簡單。

以上代碼在Python3.5以上版本測試通過。


↓ 頭條的代碼排版格式有點問題,沒縮進,請點擊下面的“瞭解更多”鏈接可查看完整的詳細。


分享到:


相關文章: