Files
sbnews/server/app/common/command/CrawlerCommand.php
T
2026-06-11 12:15:29 +08:00

94 lines
2.7 KiB
PHP

<?php
namespace app\common\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Argument;
class CrawlerCommand extends Command
{
protected function configure()
{
$this->setName('crawler')
->addArgument('action', Argument::REQUIRED, '执行动作: standings/schedule/all/menu')
->setDescription('懂球帝数据爬虫');
}
protected function execute(Input $input, Output $output)
{
$action = $input->getArgument('action');
$allowed = [
'standings',
'schedule',
'all',
'menu',
'news',
'league_news',
'article_content',
'live',
'lottery',
'lottery_draw',
'lottery_draw_force',
'match_data',
'init-db',
'test',
'csl_match',
'nba_match',
'cba_match',
'epl_match',
'bundesliga_match',
'laliga_match',
'seriea_match',
'ligue1_match',
'ucl_match',
'uel_match',
'tennis_match',
'esports_match',
'sports_match',
'truth_social',
'crypto_news',
'lottery_news',
'taiwan_lottery_news',
'hkjc_lottery_news',
'lottery_community',
'nba_news',
'cba_news',
'article_content_fetch',
'fifa_worldcup_news',
'dqd_worldcup',
'match_finish',
'live_detail',
];
if (!in_array($action, $allowed)) {
$output->writeln("<error>不支持的动作: {$action}, 可选: " . implode('/', $allowed) . "</error>");
return;
}
// 文件锁防止同一动作并发执行
$lockFile = runtime_path() . "crawler_{$action}.lock";
$fp = fopen($lockFile, 'w');
if (!flock($fp, LOCK_EX | LOCK_NB)) {
$output->writeln("<comment>[Crawler] {$action} 正在执行中,跳过本次</comment>");
fclose($fp);
return;
}
try {
$crawlerDir = app()->getRootPath() . 'public/dongqiudi-crawler';
$venvPython = $crawlerDir . '/venv/bin/python3';
$python = file_exists($venvPython) ? $venvPython : 'python3';
$cmd = "cd {$crawlerDir} && {$python} main.py {$action} 2>&1";
$output->writeln("<info>[Crawler] 执行: {$cmd}</info>");
$result = shell_exec($cmd);
$output->writeln($result ?: '(无输出)');
} finally {
flock($fp, LOCK_UN);
fclose($fp);
@unlink($lockFile);
}
}
}