mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-18 05:04:51 +08:00
add weather bot example
This commit is contained in:
parent
689076d97c
commit
485fa5476c
107
docs/advanced/example/weather-bot.md
Normal file
107
docs/advanced/example/weather-bot.md
Normal file
@ -0,0 +1,107 @@
|
||||
# 基于词性分析和魅族天气的天气查询机器人
|
||||
|
||||
本文将基于 [`jieba-php`](https://github.com/fukuball/jieba-php) 中文分词库以及 [魅族天气 API](https://github.com/shichunlei/-Api/blob/master/MeizuWeather.md) 开发一个天气查询机器人。
|
||||
|
||||
## 结果演示
|
||||

|
||||
尾部的随机表情并非本教程的一部分。
|
||||
|
||||
## 逻辑编写
|
||||
|
||||
[`jieba-php`](https://github.com/fukuball/jieba-php) 是目前比较好用的中文分词库,虽然最近的维护并不活跃,但已足够我们的需求:
|
||||
```shell
|
||||
composer require fukuball/jieba-php:dev-master
|
||||
```
|
||||
|
||||
以下代码使用了本文作者自行编写的天气查询库,需要进行引入:
|
||||
```shell
|
||||
composer require sunxyw/weather
|
||||
```
|
||||
您也可以将以下代码自行改写为直接调用魅族天气 API,详情请参阅[魅族天气 API 文档](https://github.com/shichunlei/-Api/blob/master/MeizuWeather.md)。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Bot\Module\SmartChat;
|
||||
|
||||
use Fukuball\Jieba\Jieba;
|
||||
use Fukuball\Jieba\Posseg;
|
||||
use Sunxyw\Weather\Weather;
|
||||
use ZM\Annotation\CQ\CQCommand;
|
||||
use ZM\Console\Console;
|
||||
|
||||
class WeatherReport
|
||||
{
|
||||
/**
|
||||
* 查询天气
|
||||
*
|
||||
* @CQCommand(keyword="天气")
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function cmdQueryWeather(): string
|
||||
{
|
||||
// 分词以及词性分析需要载入字典到内存
|
||||
$original_memory_limit = ini_get('memory_limit');
|
||||
ini_set('memory_limit', '600M');
|
||||
// 此处为了节省内存选用了小词典,但部分词语可能无法正确识别
|
||||
Jieba::init(['dict' => 'small']);
|
||||
Posseg::init();
|
||||
|
||||
// 分词并进行词性分析
|
||||
$seg_list = Posseg::cut(ctx()->getMessage());
|
||||
$tags = array_column($seg_list, 'tag');
|
||||
// 找出词性为 ns(地名)的单词
|
||||
$location_index = array_search('ns', $tags, true);
|
||||
$location = $seg_list[$location_index]['word'];
|
||||
|
||||
// 部分情况下此处无法正常限制内存,不影响正常使用
|
||||
ini_set('memory_limit', $original_memory_limit);
|
||||
|
||||
// 此处引入了本文作者自己写的天气库
|
||||
$w = new Weather();
|
||||
try {
|
||||
$report = $w->getWeather($location);
|
||||
} catch (\InvalidArgumentException) {
|
||||
return '城市输入错误';
|
||||
} catch (\JsonException $e) {
|
||||
Console::warning("天气查询失败:{$e->getMessage()}");
|
||||
return '天气查询失败';
|
||||
}
|
||||
|
||||
$template = <<<EOF
|
||||
%s天气:%s
|
||||
温度:%s℃
|
||||
湿度:%s%%
|
||||
风向:%s %s
|
||||
空气质量:%s
|
||||
------------------------------
|
||||
未来三天天气:
|
||||
%s:%s,日间%s℃,夜间%s℃,吹%s %s
|
||||
%s:%s,日间%s℃,夜间%s℃,吹%s %s
|
||||
%s:%s,日间%s℃,夜间%s℃,吹%s %s
|
||||
EOF;
|
||||
$args = [
|
||||
$report->getCity(),
|
||||
$report->getRealtime()['weather'],
|
||||
$report->getRealtime()['temperature'],
|
||||
$report->getRealtime()['humidity'],
|
||||
$report->getRealtime()['wind_direction'],
|
||||
$report->getRealtime()['wind_speed'],
|
||||
$report->getRealtime()['air_quality'],
|
||||
];
|
||||
foreach (array_slice($report->getForecastDaily(), 0, 3) as $forecast) {
|
||||
$args[] = $forecast['date'];
|
||||
$args[] = $forecast['weather'];
|
||||
$args[] = $forecast['temperature']['day'];
|
||||
$args[] = $forecast['temperature']['night'];
|
||||
$args[] = $forecast['wind_direction'];
|
||||
$args[] = $forecast['wind_speed'];
|
||||
}
|
||||
return vsprintf($template, ...$args);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user