Использование Goutte с Symfony2 в контроллере

Я пытаюсь очистить страницу, и я не очень хорошо знаком с 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
    //     ));
  }

}


person Kenny    schedule 16.03.2015    source источник
comment
ну, это хорошая практика, если несколько действий контроллера выполняют одно и то же, хорошей практикой является использование сервисного уровня.   -  person john Smith    schedule 17.03.2015
comment
Будет ли сервисный уровень еще одним дополнением к MVC? Так что MVCS почти?   -  person Kenny    schedule 17.03.2015
comment
нет службы, просто класс, это что-то очевидное, оно поднимается из DRY. например, в вашем классе сервера у вас есть function getText($url){.., все ваши контроллеры могут запрашивать службу, например echo $service->getText('/foo'), вместо того, чтобы повторять один и тот же код.   -  person john Smith    schedule 17.03.2015


Ответы (2)


Я не уверен, что слышал о «хорошей практике» в отношении парсинга, но вы можете найти ее в книге Руководство архитектора PHP по парсингу веб-страниц с помощью PHP.

Вот некоторые рекомендации, которые я использовал в своих собственных проектах:

  1. Очистка — медленный процесс, рассмотрите возможность делегирования этой задачи фоновому процессу.
  2. Фоновый процесс обычно запускается как задание cron, выполняющее приложение CLI, или постоянно работающий рабочий процесс.
  3. Используйте систему управления процессами для управления вашими работниками. Взгляните на supervisord.
  4. Сохраняйте каждый очищенный файл («сырую» версию) и регистрируйте каждую ошибку. Это позволит вам обнаружить проблемы. Используйте Rackspace Cloud Files или AWS S3 для архивирования этих файлов.
  5. Используйте инструмент консоли Symfony2, чтобы создать команды для запуска парсера. Вы можете сохранить команды в своем пакете в каталоге 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 в свою команду следующим образом:

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();
    }
}
person Onema    schedule 16.03.2015

Вам следует взять Symfony-Controller, если вы хотите вернуть ответ, например, вывод в формате html.

если вам нужна только функция для вычисления или хранения данных в базе данных, вам следует создать сервис класс, который представляет функциональность вашего Crawler, например

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

и для его выполнения я бы использовал консольную команду

Если вы хотите вернуть ответ, используйте контроллер

person john Smith    schedule 16.03.2015