封裝簡易爬蟲類,支援最大深度控制、URL 去重、僅跟隨同域/同前綴連結、檢查 HTTP 200 狀態碼。
class Crawler {
private int $maxDepth = 5;
private array $visited = [];
private string $baseUrl;
public function __construct(string $baseUrl, int $maxDepth = 5) {
$this->baseUrl = rtrim($baseUrl, '/');
$this->maxDepth = $maxDepth;
}
public function crawl(string $url, int $depth = 0): array {
if ($depth >= $this->maxDepth) return $this->visited;
$url = $this->normalize($url);
if (isset($this->visited[$url])) return $this->visited;
$headers = @get_headers($url, 1);
if (!$headers || strpos($headers[0], '200') === false) return $this->visited;
$this->visited[$url] = true;
$html = @file_get_contents($url);
if (!$html) return $this->visited;
if (preg_match_all('/https?:\/\/[^\s"\'<>]+/i', $html, $m)) {
foreach ($m[0] as $link) {
if (str_starts_with($link, $this->baseUrl)) {
$this->crawl($link, $depth + 1);
}
}
}
return $this->visited;
}
private function normalize(string $url): string {
return rtrim(parse_url($url, PHP_URL_SCHEME) . '://' . parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH), '/');
}
public function getVisited(): array {
return array_keys($this->visited);
}
}
$crawler = new Crawler('https://example.com', 3);
$urls = $crawler->crawl('https://example.com');
print_r($urls);
robots.txt(robots-txt-parser 库)。sleep()、Token Bucket、Guzzle 中介軟體。$visited 到 Redis/資料庫。amphp/http-client、ReactPHP、Swoole。