c语言编程笔录

首页 >   > 笔记大全

笔记大全

PHP网络爬虫爬取知乎的方法

更新时间:2023-10-06

第一段:预备知识

在爬取网页之前,我们需要对于一些预备知识有所了解。首先,我们需要了解知乎的页面结构,其中包含需要爬取的数据属性所在的 HTML 元素 ID 或 CSS 类名。比如,如果我们需要爬取知乎某个话题下的所有问题,那么我们需要找到该话题页面中所有问题的链接,这里我们可以使用 Chrome 浏览器自带的开发者工具(F12),定位到该页面中包含问题链接的 HTML 元素,获取该元素的 ID 或 CSS 类名。

// 使用 jQuery 获取元素 ID 为 "questions" 的所有链接
var links = $("#questions a")

其次,我们需要选择一种适合于爬取网页的编程语言和爬虫框架。这里我们选择 PHP 语言和 Goutte 爬虫框架。Goutte 是 PHP 的一个 Web 爬虫框架,它提供了便捷的方法来对 HTML 页面进行检索和操作。

// 使用 Composer 安装 Goutte
composer require fabpot/goutte

第二段:抓取页面数据

使用 Goutte 打开知乎特定页面,可以使用 Goutte 的 start 方法。start 方法返回了一个 “Crawler” 对象。可以把 Crawler 对象理解为一个方便对页面进行检索和操作数据的工具。

use Goutte\Client;

$client = new Client();
$crawler = $client->request('GET', 'https://www.zhihu.com');

下面给出查找 HTML 元素的方法例子。首先通过浏览器的开发者工具定位到该元素的 HTML 标签及其 ID 或 CSS 类名,然后使用 Goutte 选择器方法获取该元素。

// 查找 ID 为 "question-title" 的问题标题
$title = $crawler->filter('#question-title')->text();

第三段:使用循环遍历网页上的数据

获取知乎中某话题下所有问题的链接,需要在页面上逐步翻页,一般需要考虑循环来完成这个过程,不断检查是否存在下一页的链接。使用 Goutte 提供的 selectLink 方法可以方便地获取页面上的某个链接,并跳转到该链接对应的页面上。

// 获取第一页问题列表中每个问题的链接
$links = $crawler->filter('.question_link')->extract(['href']);
foreach ($links as $link) {
    // 访问问题详情页
    $crawler = $client->click($crawler->selectLink($link)->link());
    // 获取问题内容
    $question = $crawler->filter('.QuestionPage')->text();
}

第四段:保存数据到数据库

最后,我们需要将爬取到的数据保存到数据库中。使用 PHP 标准库 PDO 可以方便地处理数据库连接,提供简单的 ORM 模型。在以下示例代码中,我们将所有爬取到的问题内容插入到 MySQL 数据库的 questions 表中。

// 连接 MySQL 数据库
$pdo = new PDO('mysql:host=localhost;dbname=mydatabase', 'username', 'password');
// 准备插入语句
$stmt = $pdo->prepare("INSERT INTO questions (title, content) VALUES (:title, :content)";
foreach ($links as $link) {
    // 访问问题详情页
    $crawler = $client->click($crawler->selectLink($link)->link());
    // 获取问题内容
    $title = $crawler->filter('#question-title')->text();
    $content = $crawler->filter('.QuestionPage')->text();
    // 执行插入语句
    $stmt->execute([
        ':title' => $title,
        ':content' => $content
    ]);
}