在Controller中使用Goutte和Symfony2

时间:2015-03-16 21:01:47

标签: php symfony web-scraping goutte

我试图抓一页,我对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
    //     ));
  }

}

2 个答案:

答案 0 :(得分:4)

我不确定我是否听说过“好的做法”,但是你可以在书中找到一些PHP Architect's Guide to Web Scraping with PHP

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

  1. 刮痧是一个缓慢的过程,请考虑将该任务委派给后台进程。
  2. 后台进程通常作为执行CLI应用程序或持续运行的工作程序的cron作业运行。
  3. 使用过程控制系统来管理您的员工。看看supervisord
  4. 保存每个已删除的文件(“原始”版本),并记录每个错误。这将使您能够检测问题。使用Rackspace Cloud Files或AWS S3归档这些文件。
  5. 使用Symfony2 Console tool创建运行刮刀的命令。您可以在Command目录下的命令中保存命令。
  6. 使用以下标志运行Symfony2命令以防止内存不足:php app/console scraper:run example.com --env=prod --no-debug其中app / console是Symfony2控制台应用程序所在的位置,scraper:run是命令的名称,example.com是一个用于指示要抓取的页面的参数, - env = prod --no-debug是您应该用于在生产中运行的标志。请参阅下面的代码。
  7. 将Goutte客户端注入您的命令中:
  8. Ontf / ScraperBundle /资源/ 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();
        }
    }
    

答案 1 :(得分:0)

如果你想要回复一个响应,你应该带一个Symfony-Controller,例如html输出。

如果你只需要在数据库中计算或存储东西的函数, 您应该创建一个代表Crawler功能的Service类,e.G

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

并执行它我将使用Console Command

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