PHP爬虫框架 第1章 Goutte PHP爬虫框架 第1章 Goutte

2024-04-02

一、介绍

Goutte 库非常有用,它可以为您提供有关如何使用 PHP 抓取内容的出色支持。

基于 Symfony 框架,它提供了 API 来抓取网站并从 HTML / XML响应中抓取数据,它是免费开源的。

基于 OOP 的编程思想,非常适合大型项目的爬虫,同时它有着还不错的解析速度。

它需要 php 满足 5.5+。

Goutte:支持 JavaScript,支持 Cookie

二、安装

通过 composer 安装

composer require fabpot/goutte

三、例子

3.1、简单例子

use Goutte\Client;
$client = new Client();
$crawler = $client->request('GET', 'http://www.baidu.com/');
$crawler->filter('a')->each(function ($node) {
   print $node->attr('href');
});

该实例访问百度首页,获取所有链接的地址并输出。首先我们创建了一个 Client 实例,然后使用 request 方法获取百度首页 HTML 内容,接着使用 filter 方法选择 DOM 节点,并使用 each 方法进行循环处理每个节点。

3.2、获取页面内容

通过 Goutte 可以获取网页的所有内容,如标题、Meta 标签、CSS 样式、JavaScript 脚本等。

下面是一个实例:

use Goutte\Client;
$client = new Client();
$crawler = $client->request('GET', 'https://www.sina.com.cn/');
$title = $crawler->filterXPath('//title')->text();
$meta = $crawler->filterXPath('//meta[@name="description"]')->attr('content');
$css = $crawler->filterXPath('//link[@rel="stylesheet"]')->attr('href');
$script = $crawler->filterXPath('//script[@src]')->attr('src');
echo "title: ".$title;
echo "meta_description: ".$meta;
echo "css: ".$css;
echo "script: ".$script;

上述实例获取了新浪网首页的标题、Meta 标签中的 description、CSS 样式文件和 JavaScript 脚本文件,并输出到控制台中。

3.3、表单提交

在某些情况下,我们需要模拟用户登录并提交表单来获取目标数据。

Goutte 可以通过类似用户行为的方式提交表单。

下面是一个实例:

use Symfony\Component\DomCrawler\Form;

$client = new Client();
$crawler = $client->request('GET', 'http://localhost/login.php');

$form = $crawler->selectButton('login')->form();

$form['username'] = 'admin';
$form['password'] = '123456';

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

echo $crawler->filterXPath('//div[@class="alert alert-success"]')->text();

该实例模拟用户通过 POST 方式提交了用户名和密码,登录了本地服务器的一个测试站点,并获取了登录后的页面内容。

3.4、AJAX 请求

现如今,越来越多的网页采用了 AJAX 的技术,动态更新数据。

Goutte 同样也支持模拟 AJAX 请求并抓取返回的结果。

下面是一个实例:

use Goutte\Client;
$client = new Client();
$crawler = $client->request('GET', 'https://www.taobao.com/');
$ajax_url = $crawler->filterXPath('//a[@data-ajax]');
$response = $client->request('GET', $ajax_url->attr('href'));
echo $response->filterXPath('//title')->text();

该实例获取了淘宝首页中带 data-ajax 属性的链接地址,并使用 Goutte 进行 AJAX 请求,并输出返回的页面标题。

3.5、登录并抓取数据

在某些情况下,我们需要先登录才能抓取到目标数据。

下面是一个实例:

use Goutte\Client;
$client = new Client();
// login first
$crawler = $client->request('GET', 'http://localhost/login.php');
$form = $crawler->selectButton('login')->form();
$form['username'] = 'admin';
$form['password'] = '123456';
$crawler = $client->submit($form);
// then visit the page you want
$crawler = $client->request('GET', 'http://localhost/data.php');
echo $crawler->filterXPath('//table')->text();

该实例先模拟用户登录操作,然后再访问数据页面,并输出数据表格内容。

3.6、获取表格内容

use Goutte\Client;

$client = new Client();

$crawler = $client->request('GET', 'http://www.example.com/table.html');

$tableRows = $crawler->filter('table tr')->each(function ($row) {
   return $row->filter('td')->each(function ($cell) {
       return $cell->text();
   });
});

var_dump($tableRows);

3.7、处理 JavaScript 渲染的内容

use Goutte\Client;
use Symfony\Component\DomCrawler\Crawler;

$client = new Client();

$crawler = $client->request('GET', 'http://www.example.com');

// 等待JavaScript加载完成
$client->wait(5000, "document.readyState === 'complete'");

// 使用Crawler对象解析JavaScript渲染后的HTML内容
$javascriptRenderedHtml = $client->executeScript('return document.documentElement.outerHTML;');
$crawler = new Crawler($javascriptRenderedHtml);

$crawler->filter('h1')->each(function ($node) {
   echo $node->text()."\n";
});

3.8、使用代理访问网页

use Goutte\Client;

$client = new Client();

// 设置代理服务器
$client->setProxy('http://proxy.example.com:8080');

// 访问需要使用代理的页面
$crawler = $client->request('GET', 'http://www.example.com');

$crawler->filter('h1')->each(function ($node) {
   echo $node->text()."\n";
});

3.9、处理 XML 数据

use Goutte\Client;

$client = new Client();

$crawler = $client->request('GET', 'http://www.example.com/xml');

$xml = simplexml_load_string($crawler->html());

foreach ($xml->item as $item) {
   echo $item->title."\n";
   echo $item->description."\n";
}

3.10、获取多个页面的数据

use Goutte\Client;

$client = new Client();

$urls = [
   'http://www.example.com/page1',
   'http://www.example.com/page2',
   'http://www.example.com/page3',
];

foreach ($urls as $url) {
   $crawler = $client->request('GET', $url);

   $crawler->filter('h1')->each(function ($node) {
       echo $node->text()."\n";
   });
}

3.11、使用 cookie 访问网页

use Goutte\Client;

$client = new Client();

// 设置cookie
$client->getCookieJar()->set(new \Symfony\Component\BrowserKit\Cookie('session_id', '123'));

$crawler = $client->request('GET', 'http://www.example.com');

$crawler->filter('h1')->each(function ($node) {
   echo $node->text()."\n";
});

3.12、处理AJAX响应

use Goutte\Client;

$client = new Client();
$client->request('GET', 'http://www.example.com');

// 发送异步请求获取数据
$response = $client->getClient()->request('POST', 'http://www.example.com/ajax', [
   'headers' => ['X-Requested-With' => 'XMLHttpRequest'],
   'json' => ['key' => 'value'],
]);

// 处理响应
$data = json_decode($response->getBody(), true);
echo $data['name']."\n";
echo $data['age']."\n";

3.13、从 JSON 数据中获取内容

use Goutte\Client;

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

$jsonData = json_decode($crawler->html());

foreach ($jsonData as $item) {
   echo $item->name."\n";
   echo $item->age."\n";
}

3.14、使用队列爬取网页

use Goutte\Client;
use Symfony\Component\DomCrawler\Link;

$client = new Client();

$queue = new \SplQueue();
$queue->enqueue('http://www.example.com/');

while (!$queue->isEmpty()) {
   $url = $queue->dequeue();

   $crawler = $client->request('GET', $url);

   $crawler->filter('a')->each(function (Link $link) use ($queue) {
       $url = $link->getUri();
       if (strpos($url, 'http://www.example.com/') === 0) {
           $queue->enqueue($url);
       }
   });

   $crawler->filter('h1')->each(function ($node) {
       echo $node->text()."\n";
   });
}

3.15、处理下载文件

use Goutte\Client;

$client = new Client();

// 访问包含文件下载链接的页面
$crawler = $client->request('GET', 'http://www.example.com/files');

// 获取下载链接并下载文件
$link = $crawler->filter('a')->eq(0)->link();
$fileContent = $client->click($link)->getContent();

// 写入文件
file_put_contents('/path/to/downloaded/file', $fileContent);

3.16、获取图片链接并下载图片

use Goutte\Client;

$client = new Client();

$crawler = $client->request('GET', 'http://www.example.com/images');

// 获取图片链接并下载图片
$crawler->filter('img')->each(function ($image) use ($client) {
   $imageUrl = $image->attr('src');
   $imageContent = $client->request('GET', $imageUrl)->getContent();

   // 写入文件
   file_put_contents('/path/to/downloaded/image.jpg', $imageContent);
});

3.17、关闭自动重定向

use Goutte\Client;

$client = new Client(['allow_redirects' => false]);

$crawler = $client->request('GET', 'http://www.example.com');

if ($client->getResponse()->getStatusCode() == 301) {
   $redirectUrl = $client->getResponse()->getHeader('location')[0];
   $crawler = $client->request('GET', $redirectUrl);
}

$crawler->filter('h1')->each(function ($node) {
   echo $node->text()."\n";
});

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开微信扫一扫,即可进行扫码打赏哦

阅读 162