下面我来详细讲解一下在PHP中实现简单爬虫的方法。
爬虫是一种自动化的数据抓取程序,实现简单的爬虫需要了解如下基本步骤:
Curl
或file_get_contents
等函数来获取;下面我们以一个实例来说明如何实现一个简单的爬虫。
例如,我们有一个博客网站http://www.example.com,现在我们想抓取其中的文章标题和文章链接,并存储到数据库中。
我们可以使用Curl
函数或file_get_contents
函数来获取网页内容。其中Curl
函数需要php.ini文件中启用Curl插件,但是相对来说对于数据的筛选会更加简单。file_get_contents
函数是PHP自带的函数,更加简单,但是和Curl比,筛选数据要稍微复杂一些。
示例代码:
$url = "http://www.example.com";
$html = file_get_contents($url);
使用正则表达式或XPath等方式提取所需信息。这里我们使用XPath。
假设我们要抓取的信息结构为:
<div class="article">
<h1><a href="http://www.example.com/article1.html">Article Title</a></h1>
</div>
我们需要抓取的信息是文章标题和链接。我们可以使用XPath查询所有的h1
标签下的a
标签,并分别提取其中的text
和href
属性。示例代码:
$doc = new DomDocument();
$doc->loadHTML($html);
$xpath = new DomXPath($doc);
$articles = $xpath->evaluate('//div[@class="article"]');
foreach ($articles as $article) {
$title = $xpath->evaluate('string(h1/a/text())', $article);
$link = $xpath->evaluate('string(h1/a/@href)', $article);
}
最后将得到的文章标题和链接存储到数据库中,以便快速索引和查询。
示例代码:
// 假设使用 MySQL 数据库
$db = new mysqli("localhost", "username", "password", "blog_db");
$db->query("SET NAMES UTF8");
// 删除已有数据
$db->query("DELETE FROM articles");
// 插入新数据
foreach ($articles as $article) {
$title = $db->real_escape_string($xpath->evaluate('string(h1/a/text())', $article));
$link = $db->real_escape_string($xpath->evaluate('string(h1/a/@href)', $article));
$db->query("INSERT INTO articles (title, link) VALUES ('$title', '$link')");
}
这样,我们的爬虫程序就完成了。
接下来我们再看一个实例。例如,我们要爬取百度百科词条中的概述、基本信息、正文等内容。
百度百科的文章结构比较复杂,我们可以使用Curl
函数来获取HTML页面。
示例代码:
$url = "https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E5%A4%A7%E9%99%86/408485";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($curl);
curl_close($curl);
为了提取百度百科词条的概述、基本信息和正文,我们可以使用XPath表达式和CSS选择器。
$doc = new DomDocument();
$doc->loadHTML($html);
$xpath = new DomXPath($doc);
// 概述
$summary = $xpath->query('//div[@class="lemma-summary"]/div[@class="para"]')->item(0)->nodeValue;
// 基本信息
$info_items = $xpath->query('//div[@class="basic-info cmn-clearfix"]/dl/*');
$info = [];
$name = "";
for ($i = 0; $i < $info_items->length; $i++) {
$item = $info_items->item($i);
switch ($item->nodeName) {
// 属性名称
case "dt":
$name = $item->nodeValue;
break;
// 属性值
case "dd":
$value = $item->nodeValue;
// 删除注释
$value = preg_replace('/<!--.*?-->/', "", $value);
$info[$name] = trim($value);
break;
}
}
// 正文
$content = $doc->getElementById("lemmaContent-0")->ownerDocument->saveHTML($doc->getElementById("lemmaContent-0"));
最后,我们可以把爬取到的结果存储到数据库或者其他文件中。
示例代码:
$db = new mysqli("localhost", "username", "password", "wiki_db");
$db->query("SET NAMES UTF8");
$insert_sql = "INSERT INTO baike_article (url, summary, content) VALUES ('{$url}', '{$summary}', '{$content}')";
$db->query($insert_sql);
$update_sql = "UPDATE baike_info SET name = ?, value = ? WHERE url = ? AND name = ?";
$stmt = $db->prepare($update_sql);
foreach ($info as $name => $value) {
$stmt->bind_param("ssss", $url, $value, $url, $name);
$stmt->execute();
}
这样,我们就完成了爬取百度百科词条的简单爬虫程序。