在 WordPress 插件中通过 HTTP 请求获取文章的整页源码,可以使用 WordPress 内置的 HTTP API 或 PHP 的 cURL 实现。以下是两种可靠的方法:
方法 1:使用 WordPress HTTP API(推荐)
/**
* 通过虚拟HTTP请求获取文章整页HTML源码
* @param string $url 文章完整URL
* @return string|false 成功返回HTML源码,失败返回false
*/
function get_post_html_via_http($url) {
// 发送HTTP请求
$response = wp_remote_get($url, array(
'timeout' => 30, // 超时时间(秒)
'sslverify' => false, // 跳过SSL验证(适用于本地开发)
'user-agent' => 'Mozilla/5.0 (WordPress Plugin; Virtual HTTP Request)',
));
// 检查请求结果
if (is_wp_error($response)) {
error_log('HTTP请求失败: ' . $response->get_error_message());
return false;
}
// 检查HTTP状态码
$response_code = wp_remote_retrieve_response_code($response);
if ($response_code !== 200) {
error_log("HTTP错误状态码: {$response_code}");
return false;
}
// 返回HTML源码
return wp_remote_retrieve_body($response);
}
// 使用示例
$post_url = 'https://example.com/hello-world/';
$html_content = get_post_html_via_http($post_url);
if ($html_content) {
// 成功获取源码
} else {
// 处理失败情况
}
方法 2:使用 PHP cURL(需服务器支持)
function get_post_html_via_curl($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (WordPress Plugin; Virtual HTTP Request)',
]);
$html = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($http_code !== 200 || !empty($error)) {
error_log("cURL请求失败: {$error} | HTTP状态码: {$http_code}");
return false;
}
return $html;
}
关键注意事项
- 用户代理设置
添加自定义 User-Agent 避免被服务器拦截(如WordPress Plugin Virtual Request) - 本地环境特殊处理
// 本地开发时跳过SSL验证(生产环境应启用)
add_filter('https_ssl_verify', '__return_false');
add_filter('https_local_ssl_verify', '__return_false');
- 缓存机制(提升性能)
// 添加缓存示例(缓存1小时)
$cache_key = 'post_html_' . md5($url);
$cached = get_transient($cache_key);
if ($cached) return $cached;
$html = get_post_html_via_http($url);
if ($html) set_transient($cache_key, $html, HOUR_IN_SECONDS);
- 权限验证
如果目标文章需要登录访问:
// 添加Cookie传递(示例)
$cookies = [];
foreach ($_COOKIE as $name => $value) {
$cookies[] = "$name=" . urlencode($value);
}
$options['headers'] = ['Cookie: ' . implode('; ', $cookies)];
完整插件实现建议
/*
Plugin Name: Post HTML Fetcher
Description: 通过虚拟HTTP请求获取文章整页源码
*/
add_action('admin_menu', function() {
add_management_page(
'获取文章源码',
'文章源码工具',
'manage_options',
'post-html-fetcher',
'render_fetcher_page'
);
});
function render_fetcher_page() {
// 安全验证
if (!current_user_can('manage_options')) return;
$html = '';
if (isset($_POST['fetch_url'])) {
check_admin_referer('fetch_html_action');
$html = get_post_html_via_http(esc_url_raw($_POST['fetch_url']));
}
?>
<div class="wrap">
<h1>获取文章HTML源码</h1>
<form method="post">
<?php wp_nonce_field('fetch_html_action'); ?>
<input type="url" name="fetch_url" required
placeholder="https://example.com/your-post/" style="width:70%">
<button type="submit" class="button button-primary">获取源码</button>
</form>
<?php if ($html) : ?>
<textarea rows="25" style="width:100%; margin-top:20px"><?= esc_textarea($html) ?></textarea>
<?php endif; ?>
</div>
<?php
}
// 此处插入前面的get_post_html_via_http函数
常见问题解决方案
- 403禁止访问
- 添加
referer请求头:'headers' => ['Referer' => site_url()] - 使用WP REST API替代:
/wp-json/wp/v2/posts/<id>?context=edit
- 性能优化
// 限制每分钟请求次数
$transient_key = 'html_fetch_rate_limit';
if (get_transient($transient_key)) {
wp_die('请求过于频繁,请稍后再试');
}
set_transient($transient_key, true, MINUTE_IN_SECONDS);
- 大文件处理
// 增加超时时间
$options['timeout'] = 120;
// 分段读取
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) {
file_put_contents($tmp_file, $data, FILE_APPEND);
return strlen($data);
});
这些方法完全遵循 WordPress 插件开发标准,兼容各种主机环境,并处理了安全验证、错误日志、性能优化等关键问题。

