在控制器中使用带有 Symfony2 的 Goutte


Using Goutte with Symfony2 in Controller

我正在尝试抓取一个页面,但我对php框架不是很熟悉,所以我一直在尝试学习Symfony2。我已经启动并运行了它,现在我正在尝试使用Goutte。它安装在供应商文件夹中,我有一个用于抓取项目的捆绑包。

问题是,从Controller上刮下来是好的做法吗?又如何?我一直在寻找,但无法弄清楚如何使用捆绑包中的Goutte,因为它深埋在文件结构中。

<?php
namespace ontf'scraperBundle'Controller;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
use Goutte'Client;
class ThingController extends Controller
{
  public function somethingAction($something)
  {
    $client = new Client();
    $crawler = $client->request('GET', 'http://www.symfony.com/blog/');
    echo $crawler->text();

    return $this->render('scraperBundle:Thing:index.html.twig');
    // return $this->render('scraperBundle:Thing:index.html.twig', array(
    //     'something' => $something
    //     ));
  }

}

我不确定我是否听说过"良好实践",但你可以在 PHP 架构师指南 Web Scraping with PHP 中找到一些。

这些是我在自己的项目中使用的一些准则:

  1. 抓取是一个缓慢的过程,请考虑将该任务委派给后台进程。
  2. 后台进程通常作为执行 CLI 应用程序或持续运行的工作线程的 cron 作业运行。
  3. 使用过程控制系统来管理您的工人。看看主管
  4. 保存每个抓取的文件("原始"版本),并记录每个错误。这将使您能够检测问题。使用 Rackspace Cloud Files 或 AWS S3 存档这些文件。
  5. 使用Symfony2控制台工具创建命令来运行抓取程序。您可以将命令保存在命令目录下的捆绑包中。
  6. 使用以下标志运行 Symfony2
  7. 命令,以防止内存不足: php app/console scraper:run example.com --env=prod --no-debug 应用程序/控制台是 Symfony2 控制台应用程序所在的位置,scraper:run 是命令的名称,example.com 是一个参数,用于指示要抓取的页面,而 --env=prod --no-debug 是您应该用于在生产中运行的标志。 例如,请参阅下面的代码。
  8. 将 Goutte 客户端注入到您的命令中,如下所示:

Ontf/ScraperBundle/Resources/services.yml

services:
    goutte_client:
        class: Goutte'Client
    scraperCommand:
        class:  Ontf'ScraperBundle'Command'ScraperCommand
        arguments: ["@goutte_client"]
        tags:
            - { name: console.command }

您的命令应如下所示:

<?php
// Ontf/ScraperBundle/Command/ScraperCommand.php
namespace Ontf'ScraperBundle'Command;
use Symfony'Component'Console'Command'Command;
use Symfony'Component'Console'Input'InputArgument;
use Symfony'Component'Console'Input'InputInterface;
use Symfony'Component'Console'Input'InputOption;
use Symfony'Component'Console'Output'OutputInterface;
use Goutte'Client;
abstract class ScraperCommand extends Command
{
    private $client;
    public function __construct(Client $client)
    {
        $this->client = $client;
        parent::__construct();
    }
    protected function configure()
    {
        ->setName('scraper:run')
            ->setDescription('Run Goutte Scraper.')
            ->addArgument(
                'url',
                InputArgument::REQUIRED,
                'URL you want to scrape.'
            );
    }
    protected function execute(InputInterface $input, OutputInterface $output) 
    {
        $url = $input->getArgument('url');
        $crawler = $this->client->request('GET', $url);
        echo $crawler->text();
    }
}

如果你想返回一个响应,你应该使用一个Symfony-Controller,例如一个html输出。

如果你只需要计算或存储数据库中的东西的函数,您应该创建一个表示爬虫功能的 Service 类,例如

class CrawlerService
{
    function getText($url){
        $client = new Client();
        $crawler = $client->request('GET', $url);
        return $crawler->text();
    }

为了执行它,我将使用控制台命令

如果要返回响应,请使用控制器