使用 PHP 编程语言进行网络抓取

指南, 如何, 搜索, 2024 年 12 月 25 日5 分钟阅读

对于需要从网络中提取和分析信息的开发人员和数据分析师来说,网络搜索已经成为一种必不可少的工具。无论是跟踪产品价格、收集研究数据,还是构建自定义仪表板,网络搜索都能为您提供无限可能。

如果你是 PHP 爱好者,那么Goutte是一个非常棒的库,可以满足你的网络搜索需求。 Goutte轻巧、用户友好、功能强大,它将Guzzle 的HTTP 客户端功能与Symfony 的 DomCrawler相结合,实现了流畅、高效的网络抓取。

本指南将带您了解使用Goutte进行 PHP 网络刮擦的基础知识--从安装和第一个脚本到表单处理和分页等高级技术。

为什么选择 Goutte 进行网络抓取?

由于种种原因,Goutte在开发人员中颇受欢迎,成为 PHP 的首选搜索库之一:

  • 简洁明了的应用程序接口Goutte 提供简洁直观的界面,即使是初学者也很容易上手。
  • 无缝集成:它将 HTTP 请求与 HTML 解析相结合,无需使用单独的库。
  • 功能强大: Goutte 支持会话处理、cookie 管理和以编程方式提交表单等高级功能。
  • 新手易用,功能强大:从最简单的刮擦任务到更复杂的项目,它都能满足你的一切需求。

无论您是 PHP 的新手还是经验丰富的开发人员,Goutte 都能在简单和强大之间取得理想的平衡。

安装 Goutte

在开始编码之前,确保必要的先决条件已经到位:

  • 已安装 PHP:确保在开发环境中安装了PHP 7.3或更高版本。使用此链接直接下载 PHP。
  • 已安装 Composer:需要使用Composer来管理依赖关系和安装Goutte

要安装Goutte,只需在终端运行以下命令即可:

composer requirefabpot/goutte

安装完成后,请在项目中要求使用 Composer 的自动加载器,以验证能否访问该库:

需要 'vendor/autoload.php';

现在你可以开始刮削了!

使用 Goutte 创建你的第一个网络抓取脚本

让我们从一个简单的例子开始。我们将使用 Goutte 抓取一个网页的标题。下面是基本脚本:

获取并显示页面标题

<?php
require 'vendor/autoload.php';

use Goutte\Client;

// Initialize Goutte Client
$client = new Client();

// Send a GET request to the target URL
$crawler = $client->request('GET', 'https://books.toscrape.com/');

// Extract the title of the page
$title = $crawler->filter('title')->text();
echo "Page Title: $title\n";

// Extract the titles of the first 5 books
echo "First 5 Book Titles:\n";
$crawler->filter('.product_pod h3 a')->slice(0, 5)->each(function ($node) {
    echo "- " . $node->attr('title') . "\n";
});
?>

输出:

页面标题: 所有产品 | 搜索书籍 - 沙盒
前 5 个书名:
- 阁楼上的灯光
- 倾倒天鹅绒
- 唤醒
- 利器
- 智人:人类简史

就是这么简单!只需几行代码,您就可以获取并显示 标题标签。

从网页中提取数据

一旦学会了如何获取网页,下一步就是提取特定数据,例如从特定 HTML 元素中提取链接或内容。

Extracting All Links (`<a>` Tags)

下面的脚本提取了 href 所有 <a> 网页上的标签:

<?php
require 'vendor/autoload.php';

use Goutte\Client;

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

// Extract all <a> tags
$links = $crawler->filter('a')->each(function ($node) {
    return $node->attr('href');
});

// Print all extracted links
foreach ($links as $link) {
    echo $link . "\n";
}

这将返回页面上的所有超链接。

按类别或 ID 提取内容

通过使用 身份证 选择器。在本例中,我们将使用 图书搜索网站.具体来说,我们将搜索每本书的信息,因为它们都共享同一个类、 产品模块.网站上是这样显示的:

下面举例说明如何使用 Goutte 实现这一功能:

<?php
require 'vendor/autoload.php';

use Goutte\Client;

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

// Extract all <a> tags
$links = $crawler->filter('a')->each(function ($node) {
    return $node->attr('href');
});

// Print all extracted links
foreach ($links as $link) {
    echo $link . "\n";
}

// Extract elements with class 'product_pod'
$products = $crawler->filter('.product_pod')->each(function ($node) {
    return $node->text();
});

// Print all extracted product details
foreach ($products as $product) {
    echo $product . "\n";
}

页面间导航

现在,让我们来探讨如何在页面之间导航或分页。在我们使用的示例页面中,有一个 "下一页 "按钮可以分页到下一页。我们将利用这个按钮来实现分页。

首先,我们将使用按钮的 属性的值为 下一个 .在这个元素中,有一个 <a> 标签,其中包含下一页的 URL。通过提取该 URL,我们可以使用它发送一个新请求,并无缝地移动到下一页面。 下一个 按钮。

下面是实现这一目标的代码:

<?php
require 'vendor/autoload.php';

use Goutte\Client;

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

// Handle pagination using the 'next' button
while ($crawler->filter('li.next a')->count() > 0) {
    $nextLink = $crawler->filter('li.next a')->attr('href');
    $crawler = $client->request('GET', 'https://books.toscrape.com/catalogue/' . $nextLink);
    
    // Extract and print the current page URL
    echo "Currently on: " . $crawler->getUri() . "\n";
}

使用这种方法,您可以在页面之间自动导航,并继续搜索数据。

使用 Goutte 处理表单

Goutte 还能处理表单。为了演示这一功能,我们将使用这个网站,它只有一个输入框,如下图所示:

下面是提交该表单的代码:

<?php
require 'vendor/autoload.php';

use Goutte\Client;

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

// Submit the search form with a query
$form = $crawler->selectButton('Search')->form();
$form['q'] = 'Canada';

$crawler = $client->submit($form);

// Extract and print the results
$results = $crawler->filter('.team')->each(function ($node) {
    return $node->text();
});

foreach ($results as $result) {
    echo $result . "\n";
}

该脚本会填写一个名为 q 值为 网络搜刮 并提交。从这里,你可以从搜索结果页面中提取内容,就像前面的例子一样。

错误处理和最佳做法

处理网络错误

始终添加错误处理功能,以处理网络连接失败或 URL 不存在等意外情况。

<?php
require 'vendor/autoload.php';

use Goutte\Client;

$client = new Client();

try {
    $crawler = $client->request('GET', 'https://invalid-url-example.com');
    echo "Page title: " . $crawler->filter('title')->text();
} catch (Exception $e) {
    echo "An error occurred: " . $e->getMessage();
}
}

尊重 Robots.txt

网络抓取应始终以道德和负责任的方式进行。robots.txt "文件是网站用于与网络爬虫交流的简单文本文件,概述了网站的哪些部分可以访问,哪些部分不可以访问。在进行刮擦之前,请务必检查 `robots.txt` 文件,以确保您遵守网站规则并尊重其条款。忽视这些准则可能会导致法律和道德问题,因此请务必将此步骤作为刮擦过程中的优先事项。

了解更多 robots.txt 这里.

速率限制

请保持礼貌,避免在短时间内发送过多请求,因为这会使服务器不堪重负,影响其他用户的使用。好的做法是在每次请求之间留出较短的延迟时间,以尽量减少服务器的负荷,确保服务器能有效处理流量。采取这些措施不仅有助于保持服务器的稳定性,还能体现出对共享资源的负责和体贴。

sleep(1);// 在两次请求之间等待 1 秒钟

常见陷阱

  • 许多现代网站都依赖JavaScript来加载内容,这意味着传统的刮擦工具可能无法捕获您需要的所有数据。PuppeteerSelenium等工具可以模拟用户交互,并像浏览器一样加载内容。
  • 确保刮擦的 HTTPS 端点显示有效证书,以免出错。无效或过期的证书会导致您的搜刮失败或引发安全问题。刮擦前请务必验证证书状态,并考虑使用能无缝处理这些问题的库。

结论

网络刮擦是一种高效收集数据的强大工具,但它需要一种负责任和深思熟虑的方法,以避免常见的陷阱并确保合乎道德的使用。通过遵守网站服务条款、在请求之间实施适当的延迟以及使用能够处理动态内容的工具等最佳实践,您可以创建一个既能有效执行又能最大限度减少对服务器影响的刮擦工具。此外,验证 HTTPS 证书和注意安全考虑因素将保护您的刮擦工具及其收集的任何数据。通过适当的规划和执行,网络搜刮可以成为研究、分析和创新的宝贵资源。