刚刚去下载了一个发现各种报错,而且拿回来的图片1MB多,对带宽小的服务器来说是致命打击。
接口就不提供了,自己找一找吧,这个网上很多免费的。
发现有个bug,直接往 $wpdb->posts
写记录,绕过了 WordPress 的发布流程,因此 没有触发 wp_insert_post()
等钩子 会导致明明发布了却显示404
重新改了一下:
<?php
/**
* 获取每天60秒读懂世界的内容并发布到WordPress
* 修复了数组访问和文件处理的错误
*/
// 获取API数据
$content = curl_get('API接口');
// 调试:输出原始返回内容
if ($content === false) {
die('cURL请求失败,无法获取API数据');
}
// 调试:检查返回内容
if (empty($content)) {
die('API返回内容为空');
}
$data = json_decode($content, true);
// 调试:检查JSON解析
if (json_last_error() !== JSON_ERROR_NONE) {
die('JSON解析失败: ' . json_last_error_msg() . ',原始内容: ' . substr($content, 0, 500));
}
// 检查数据是否有效
if (!$data || !is_array($data)) {
die('API返回数据格式无效,原始内容: ' . substr($content, 0, 500));
}
// 检查是否有必要的字段
if (!isset($data['code'])) {
die('API返回数据格式错误:缺少code字段');
}
// 调试:输出code值和类型
// echo 'API返回的code值: ' . $data['code'] . ',类型: ' . gettype($data['code']) . '<br>';
// 检查API返回状态
if ($data['code'] !== 200 && $data['code'] !== '200') {
// API返回错误或数据未更新
echo 'API返回错误或数据未更新,状态码:' . $data['code'];
if (isset($data['msg'])) {
echo ',错误信息:' . $data['msg'];
}
} else {
// 验证必要字段是否存在
if (!isset($data['image']) || !isset($data['title']) || !isset($data['data'])) {
die('API返回数据格式错误:缺少必要字段');
}
$head_img = $data['image'];
// 检查图片URL是否有效
if (empty($head_img) || !filter_var($head_img, FILTER_VALIDATE_URL)) {
die('图片URL无效');
}
$ext = pathinfo($head_img, PATHINFO_EXTENSION);
// 如果无法获取扩展名,使用默认扩展名
if (empty($ext)) {
$ext = 'jpg';
}
$rand_name = date("Ymd") . '.' . $ext;
if (is_dir('60s') == false) {
mkdir('60s', 0777, true);
}
// 获取图片内容并检查是否成功
$image_content = file_get_contents($head_img);
if ($image_content === false) {
die('无法下载图片');
}
// 压缩图片以减少文件大小和带宽消耗
$compressed_image = compress_image($image_content, $ext);
if ($compressed_image === false) {
// 如果压缩失败,使用原图片
$compressed_image = $image_content;
error_log('图片压缩失败,使用原图片');
}
$s = file_put_contents('60s/' . $rand_name, $compressed_image);
if($s) {
require __DIR__ . '/wp-config.php';
global $wpdb;
date_default_timezone_set('PRC');
$post_tag_arr = array();
// 检查文章分类是否存在,获取分类ID
$category_result = $wpdb->get_row("SELECT t.term_id, tt.term_taxonomy_id from $wpdb->terms t join $wpdb->term_taxonomy tt on t.term_id = tt.term_id where t.name = '每天60秒读懂世界' and tt.taxonomy = 'category' ");
if (!$category_result) {
// 分类不存在,创建新分类
$wpdb->query("insert into $wpdb->terms (name,slug,term_group)VALUES('每天60秒读懂世界','60miao','0')");
$category_id = $wpdb->insert_id;
$wpdb->query("insert into $wpdb->term_taxonomy (term_id,taxonomy,description,parent,count)VALUES($category_id,'category','','0','1')");
$term_taxonomy_id = $wpdb->insert_id;
} else {
// 分类已存在,获取分类ID
$category_id = $category_result->term_id;
$term_taxonomy_id = $category_result->term_taxonomy_id;
}
$post_tag_arr[] = $term_taxonomy_id;
// 构建文章标题和内容
$title = sanitize_text_field($data['title']) . '!';
$content_data = isset($data['data']) ? $data['data'] : '';
// 生成SEO友好的文章别名
$post_slug = sanitize_title(date('Y-m-d') . '-60s-daily-news');
// 从内容中提取摘要(取前150个字符)
$excerpt = wp_trim_words(strip_tags($content_data), 30, '...');
if (empty($excerpt)) {
$excerpt = '每天60秒读懂世界,掌握天下事。';
}
// 构建完整的文章内容
$html = '<div class="daily-60s-content">';
$html .= '<img class="size-full wp-image-156 aligncenter" src="网站域名/60s/' . $rand_name . '" alt="每天60秒读懂世界" width="720" height="350" />';
$html .= '<div class="news-content">' . wp_kses_post($content_data) . '</div>';
$html .= '</div>';
// 定义文章标签
$post_tags = array('每天60秒', '新闻资讯', '时事热点', '每日新闻', '资讯速递');
//标题
// 检查标题是否已存在(使用预处理语句防止SQL注入)
$posts = $wpdb->get_row($wpdb->prepare("SELECT ID from $wpdb->posts where post_title = %s", $title));
if (!$posts) {
// 使用 WordPress 原生函数发布文章,确保触发所有必要的钩子
$post_data = array(
'post_author' => 作者ID,
'post_content' => $html,
'post_title' => $title,
'post_excerpt' => $excerpt,
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_name' => $post_slug,
'post_type' => 'post',
'tags_input' => $post_tags, // 直接设置标签
'post_category' => array($category_id) // 直接设置分类
);
// 使用 wp_insert_post 发布文章,这会触发所有 WordPress 钩子
$insertid = wp_insert_post($post_data, true);
// 检查是否插入成功
if (is_wp_error($insertid)) {
echo "文章发布失败: " . $insertid->get_error_message();
return;
}
// 文章发布成功
echo "文章发布成功!文章ID: " . $insertid . "<br>";
echo "文章标题: " . $title . "<br>";
echo "文章链接: " . get_permalink($insertid) . "<br>";
// wp_insert_post() 已自动处理:
// 1. 分类和标签的关联
// 2. 触发所有必要的WordPress钩子
// 3. 更新缓存和permalink
// 4. 设置正确的文章状态和时间戳
echo '文章发布成功!标题:' . $title . ',ID:' . $insertid . ',链接:' . get_permalink($insertid);
}
}
}
/**
* 压缩图片以减少文件大小
* @param string $image_data 原始图片数据
* @param string $ext 图片扩展名
* @param int $quality 压缩质量 (1-100,默认75)
* @param int $max_width 最大宽度 (默认800px)
* @param int $max_height 最大高度 (默认600px)
* @return string|false 返回压缩后的图片数据,失败时返回false
*/
function compress_image($image_data, $ext, $quality = 75, $max_width = 800, $max_height = 600) {
// 检查GD扩展是否可用
if (!extension_loaded('gd')) {
error_log('GD扩展未安装,无法压缩图片');
return false;
}
// 从字符串创建图片资源
$source_image = imagecreatefromstring($image_data);
if ($source_image === false) {
error_log('无法从图片数据创建图片资源');
return false;
}
// 获取原始图片尺寸
$original_width = imagesx($source_image);
$original_height = imagesy($source_image);
// 计算新的尺寸(保持宽高比)
$ratio = min($max_width / $original_width, $max_height / $original_height);
// 如果图片已经小于最大尺寸,且质量设置较高,可能不需要压缩
if ($ratio >= 1 && $quality >= 90) {
imagedestroy($source_image);
return $image_data; // 返回原图片
}
$new_width = (int)($original_width * $ratio);
$new_height = (int)($original_height * $ratio);
// 创建新的图片资源
$new_image = imagecreatetruecolor($new_width, $new_height);
// 处理透明背景(PNG/GIF)
if (in_array(strtolower($ext), ['png', 'gif'])) {
imagealphablending($new_image, false);
imagesavealpha($new_image, true);
$transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
imagefill($new_image, 0, 0, $transparent);
}
// 重新采样图片
imagecopyresampled($new_image, $source_image, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);
// 输出压缩后的图片到缓冲区
ob_start();
switch (strtolower($ext)) {
case 'jpg':
case 'jpeg':
imagejpeg($new_image, null, $quality);
break;
case 'png':
// PNG压缩级别:0-9,9为最高压缩
$png_quality = (int)(9 - ($quality / 100) * 9);
imagepng($new_image, null, $png_quality);
break;
case 'gif':
imagegif($new_image);
break;
case 'webp':
if (function_exists('imagewebp')) {
imagewebp($new_image, null, $quality);
} else {
// 如果不支持WebP,转换为JPEG
imagejpeg($new_image, null, $quality);
}
break;
default:
// 默认输出为JPEG
imagejpeg($new_image, null, $quality);
break;
}
$compressed_data = ob_get_contents();
ob_end_clean();
// 清理内存
imagedestroy($source_image);
imagedestroy($new_image);
// 检查压缩效果
$original_size = strlen($image_data);
$compressed_size = strlen($compressed_data);
$compression_ratio = (1 - $compressed_size / $original_size) * 100;
error_log(sprintf('图片压缩完成:原始大小 %s,压缩后 %s,压缩率 %.1f%%',
format_bytes($original_size),
format_bytes($compressed_size),
$compression_ratio
));
return $compressed_data;
}
/**
* 格式化字节大小显示
* @param int $bytes 字节数
* @return string 格式化后的大小字符串
*/
function format_bytes($bytes) {
$units = array('B', 'KB', 'MB', 'GB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, 2) . ' ' . $units[$pow];
}
/**
* 使用cURL获取远程URL内容
* @param string $url 要获取的URL地址
* @return string|false 返回获取的内容,失败时返回false
*/
function curl_get($url) {
$refer = $url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_REFERER, $refer);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 自动跟随重定向
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
// 添加更多HTTP头
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: application/json, text/plain, */*',
'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8',
'Cache-Control: no-cache'
));
$output = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 检查cURL错误
if (curl_error($ch)) {
error_log('cURL错误: ' . curl_error($ch));
curl_close($ch);
return false;
}
// 检查HTTP状态码
if ($http_code >= 400) {
error_log('HTTP错误: ' . $http_code . ', 响应内容: ' . substr($output, 0, 200));
curl_close($ch);
return false;
}
curl_close($ch);
return $output;
}
找了一圈确实也没看到几个靠谱的新闻接口,基本上免费的接口返回的都是图片。
我来一个娱乐的,新闻内容是AI写的,但是是文字的。:D
- All rights reserved.
- No part of this website, including text and images, may be reproduced, modified, distributed, or transmitted in any form or by any means, without the prior written permission of the author.
- Unauthorized commercial use is strictly prohibited.
- Unauthorized personal use is strictly prohibited.