PHP开发Telegram Bot时HTML解析模式失效问题求助
我正在用PHP开发Telegram机器人,用来推送新闻网站的内容。目标网站的HTML里有很多带内联样式的<p>标签这类元素,我尝试用下面的代码调用Telegram API发消息:
file_get_contents($path."/sendmessage?chat_id=CHAT_ID&text=HTML_CODE&parse_mode=html");
其中$path是包含机器人令牌的Telegram API地址变量。但消息一直发不出去,换成普通文本或者去掉parse_mode=html参数就能正常发送。有没有简便的方法调整代码,实现直接发送这类HTML内容?
核心原因
Telegram的parse_mode=html仅支持有限的HTML标签和属性,完全不支持内联style属性,你的HTML里大量内联样式会被判定为无效格式,导致消息发送失败。同时直接用GET拼接URL还会遇到字符转义和长度限制的问题。
具体调整步骤
清理无效HTML内容
先过滤掉Telegram不支持的标签和属性(比如所有内联style),只保留允许的元素(如<b>、<i>、<a>、<code>、<pre>、<p>等,但<p>仅作为段落分隔,样式会被忽略)。
用PHP的DOMDocument处理示例:function cleanTelegramHtml($html) { $dom = new DOMDocument(); // 处理乱码问题 @$dom->loadHTML('<?xml encoding="UTF-8">' . $html); $xpath = new DOMXPath($dom); // 移除所有style属性 foreach ($xpath->query('//@style') as $attr) { $attr->parentNode->removeAttribute($attr->nodeName); } // 移除不支持的标签 foreach ($xpath->query('//script|//style|//iframe') as $node) { $node->parentNode->removeChild($node); } return $dom->saveHTML(); }改用POST请求发送
GET请求有长度限制,且URL拼接容易出现转义错误,改用POST请求更可靠:$chatId = "CHAT_ID"; $yourOriginalHtml = "这里是你从新闻网站获取的原始HTML"; $cleanedHtml = cleanTelegramHtml($yourOriginalHtml); $apiUrl = $path . "/sendmessage"; $postData = http_build_query([ 'chat_id' => $chatId, 'text' => $cleanedHtml, 'parse_mode' => 'html' ]); $options = [ 'http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $postData ] ]; $context = stream_context_create($options); $result = file_get_contents($apiUrl, false, $context); // 可打印结果排查错误 // var_dump($result);特殊字符转义
如果清理后的HTML里还有特殊字符(如&、<、>),http_build_query会自动处理URL编码,也可以提前用htmlspecialchars处理文本内容,避免格式冲突。
补充说明
如果需要保留部分格式,只能用Telegram允许的HTML标签来实现,比如用<b>代替粗体样式、<i>代替斜体,无法保留自定义颜色、字体大小等内联样式。
内容的提问来源于stack exchange,提问作者heaven-of-intensity

