本文目录导读:

我来帮你写一个PHP批量抓取网页标题的脚本,这里有几种方案,从简单到复杂:
简单版(使用file_get_contents)
<?php
/**
* 简单版:批量抓取网页标题
* 使用 file_get_contents 直接获取网页内容
*/
// 要抓取的URL列表
$urls = [
'https://www.baidu.com',
'https://www.qq.com',
'https://www.163.com',
'https://www.sina.com.cn'
];
foreach ($urls as $url) {
try {
// 设置超时和上下文
$context = stream_context_create([
'http' => [
'timeout' => 10,
'header' => "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n"
]
]);
// 获取网页内容
$html = @file_get_contents($url, false, $context);
if ($html !== false) {
// 匹配标题
preg_match('/<title[^>]*>(.*?)<\/title>/i', $html, $matches);
$title = isset($matches[1]) ? trim($matches[1]) : '未找到标题';
echo "URL: $url\n";
echo "标题: $title\n";
echo "-------------------\n";
} else {
echo "URL: $url\n";
echo "标题: 获取失败\n";
echo "-------------------\n";
}
} catch (Exception $e) {
echo "URL: $url\n";
echo "错误: " . $e->getMessage() . "\n";
echo "-------------------\n";
}
}
?>
使用cURL(推荐,更稳定)
<?php
/**
* 使用cURL批量抓取网页标题
* cURL更稳定,支持并发请求
*/
class BatchTitleFetcher {
private $urls = [];
private $timeout = 10;
private $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
public function __construct(array $urls, $timeout = 10) {
$this->urls = $urls;
$this->timeout = $timeout;
}
/**
* 单个抓取
*/
public function fetchSingle($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_USERAGENT => $this->userAgent,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_ENCODING => '',
]);
$html = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($html === false) {
return ['error' => $error];
}
// 提取标题
if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $html, $matches)) {
return ['title' => trim($matches[1])];
}
return ['error' => '未找到标题'];
}
/**
* 批量抓取(串行)
*/
public function fetchAllSerial() {
$results = [];
foreach ($this->urls as $url) {
echo "正在抓取: $url\n";
$results[$url] = $this->fetchSingle($url);
sleep(1); // 防止请求过快
}
return $results;
}
/**
* 批量抓取(并发)
*/
public function fetchAllParallel() {
$results = [];
$handles = [];
$mh = curl_multi_init();
// 创建多个cURL句柄
foreach ($this->urls as $key => $url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_USERAGENT => $this->userAgent,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_ENCODING => '',
]);
curl_multi_add_handle($mh, $ch);
$handles[$key] = $ch;
$results[$url] = ['status' => 'pending'];
}
// 执行并发请求
$running = null;
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh);
} while ($running > 0);
// 获取结果
foreach ($handles as $key => $ch) {
$url = $this->urls[$key];
$html = curl_multi_getcontent($ch);
$error = curl_error($ch);
if ($html !== false && empty($error)) {
if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $html, $matches)) {
$results[$url] = ['title' => trim($matches[1])];
} else {
$results[$url] = ['error' => '未找到标题'];
}
} else {
$results[$url] = ['error' => $error ?: '获取失败'];
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
return $results;
}
/**
* 格式化输出结果
*/
public function printResults(array $results) {
echo "\n========== 抓取结果 ==========\n\n";
foreach ($results as $url => $result) {
echo "URL: $url\n";
if (isset($result['title'])) {
echo "标题: {$result['title']}\n";
} elseif (isset($result['error'])) {
echo "错误: {$result['error']}\n";
} else {
echo "状态: {$result['status']}\n";
}
echo "-------------------\n";
}
}
}
// 使用示例
$urls = [
'https://www.baidu.com',
'https://www.qq.com',
'https://www.163.com',
'https://www.sina.com.cn',
'https://www.taobao.com'
];
$fetcher = new BatchTitleFetcher($urls, 10);
echo "=== 串行抓取 ===\n";
$results = $fetcher->fetchAllSerial();
$fetcher->printResults($results);
echo "\n\n=== 并发抓取 ===\n";
$results = $fetcher->fetchAllParallel();
$fetcher->printResults($results);
?>
带数据库存储的完整版
<?php
/**
* 完整版:批量抓取并保存到数据库
*/
class TitleFetcher {
private $pdo;
private $timeout = 10;
public function __construct($dbConfig) {
// 数据库连接
$dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']};charset=utf8mb4";
$this->pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['password']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->createTable();
}
private function createTable() {
$sql = "CREATE TABLE IF NOT EXISTS web_titles (
id INT AUTO_INCREMENT PRIMARY KEY,
url VARCHAR(500) NOT NULL,
title VARCHAR(500),
status VARCHAR(20) DEFAULT 'success',
error_message TEXT,
fetch_time DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_url (url(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
$this->pdo->exec($sql);
}
public function fetchAndSave($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
]);
$html = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($html === false) {
$this->saveResult($url, null, 'error', $error);
return false;
}
// 提取标题
if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $html, $matches)) {
$title = trim($matches[1]);
$this->saveResult($url, $title, 'success', null);
return $title;
}
$this->saveResult($url, null, 'no_title', '未找到标题');
return null;
}
private function saveResult($url, $title, $status, $error) {
$sql = "INSERT INTO web_titles (url, title, status, error_message, fetch_time)
VALUES (:url, :title, :status, :error, NOW())
ON DUPLICATE KEY UPDATE
title = VALUES(title),
status = VALUES(status),
error_message = VALUES(error_message),
fetch_time = NOW()";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([
':url' => $url,
':title' => $title,
':status' => $status,
':error' => $error
]);
}
public function batchFetch($urls) {
$results = [];
foreach ($urls as $index => $url) {
echo "[" . ($index + 1) . "/" . count($urls) . "] 正在处理: $url\n";
$title = $this->fetchAndSave($url);
$results[$url] = $title;
if ($index < count($urls) - 1) {
// 延迟1-2秒,避免被封IP
sleep(rand(1, 2));
}
}
return $results;
}
public function getHistory($limit = 50) {
$sql = "SELECT * FROM web_titles ORDER BY fetch_time DESC LIMIT $limit";
return $this->pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
}
// 使用示例
$dbConfig = [
'host' => 'localhost',
'dbname' => 'your_database',
'user' => 'root',
'password' => 'your_password'
];
$fetcher = new TitleFetcher($dbConfig);
$urls = [
'https://www.baidu.com',
'https://www.qq.com',
'https://www.163.com',
'https://www.sina.com.cn',
'https://www.taobao.com',
'https://www.jd.com',
'https://www.tmall.com'
];
// 批量抓取
$results = $fetcher->batchFetch($urls);
// 显示结果
echo "\n========== 抓取结果 ==========\n\n";
foreach ($results as $url => $title) {
echo "URL: $url\n";
echo "标题: " . ($title ?? "失败") . "\n";
echo "-------------------\n";
}
// 查看历史记录
echo "\n========== 历史记录 ==========\n\n";
$history = $fetcher->getHistory(10);
foreach ($history as $row) {
echo "URL: {$row['url']}\n";
echo "标题: {$row['title']}\n";
echo "状态: {$row['status']}\n";
echo "时间: {$row['fetch_time']}\n";
echo "-------------------\n";
}
?>
使用建议
-
选择合适的方案:
- 简单抓取用
file_get_contents - 需要稳定性用cURL
- 需要持久化用数据库版本
- 简单抓取用
-
性能优化:
- 使用cURL多线程并发请求
- 设置合理的超时时间
- 控制请求频率,避免被封
-
注意事项:
- 遵守目标网站robots.txt
- 添加适当的User-Agent
- 处理SSL证书问题
- 支持字符编码转换
如果还有问题,请告诉我具体需求,我可以帮你调整代码!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播