PHPackages                             anilp07x/scraper\_vagas - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. anilp07x/scraper\_vagas

ActiveLibrary

anilp07x/scraper\_vagas
=======================

Motor de web scraping com estratégia leve (Guzzle + DomCrawler) ou pesada (Panther/Chrome headless) e adaptadores para sites de empresas em Angola.

03↑2900%PHP

Since Aug 25Pushed todayCompare

[ Source](https://github.com/anilp07x/job-search)[ Packagist](https://packagist.org/packages/anilp07x/scraper_vagas)[ RSS](/packages/anilp07x-scraper-vagas/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

scraper\_vagas
==============

[](#scraper_vagas)

> Motor de **web scraping** em PHP para portais de emprego e empresas em Angola — com estratégia automática **leve** (HTTP estático) ou **pesada** (Chrome headless) e adaptadores prontos a usar.

[![Packagist](https://camo.githubusercontent.com/a9ec75202d9315aac585de0723bdd433b7ceccb514590f83b5245622f7937362/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5061636b61676973742d616e696c706564726f3037253246736372617065725f76616761732d3231393646333f6c6f676f3d7061636b6167697374)](https://packagist.org/packages/anilpedro07/scraper_vagas)[![PHP](https://camo.githubusercontent.com/3e41095f4ad1c6ad78f988bd1c107f87972f334143c3ba814165a03e1f43a63c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![Symfony](https://camo.githubusercontent.com/61f7c7f1b7a4fd8d1e9e48d194c089a4baa57901ecd901ba6f857e5556fc2d8c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d446f6d437261776c657225323025324625323043737353656c6563746f722d3030303030303f6c6f676f3d73796d666f6e79266c6f676f436f6c6f723d7768697465)](https://symfony.com/)[![Guzzle](https://camo.githubusercontent.com/1545edb883794a8724f1457319526ed3c3ca170ef6c56a0efb27df9a64a3287a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f47757a7a6c652d48545450253230436c69656e742d464636463631)](https://docs.guzzlephp.org/)[![Panther](https://camo.githubusercontent.com/b50b7e0e0690ae4c99d796c9375939162fe997d555dedf35a7ef303949b779bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f50616e746865722d4368726f6d65253230486561646c6573732d303030303030)](https://github.com/symfony/panther)[![Tests](https://camo.githubusercontent.com/50d79c59949dccf804ca23e0a8a93cba6d13f08f26951fa125312e67929444ca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d3625323070617373696e672d627269676874677265656e)](https://github.com/anilp07x/job-search)

Tecnologias
-----------

[](#tecnologias)

 [![PHP](https://camo.githubusercontent.com/3d600cace7cd281a6464791cf133e1b881f14b512acbaecf715f319ab050cebb/68747470733a2f2f63646e2e73696d706c6569636f6e732e6f72672f7068702f373737424234)](https://www.php.net/) [![Composer](https://camo.githubusercontent.com/c30dacda9a4fed511b4e31190a3a477fb400ebf8911d7cd90c6bcafb848c763f/68747470733a2f2f63646e2e73696d706c6569636f6e732e6f72672f636f6d706f7365722f383835363330)](https://getcomposer.org/) [![Symfony](https://camo.githubusercontent.com/fb5e751a4e71bfb73d44cbecc3620df7fea264a391f70c5e381f748b647b400b/68747470733a2f2f63646e2e73696d706c6569636f6e732e6f72672f73796d666f6e792f303030303030)](https://symfony.com/) [![Guzzle](https://camo.githubusercontent.com/b47f1065aaeefab3defdad46f41eeb86d5031befc33190140909f654914bd661/68747470733a2f2f63646e2e73696d706c6569636f6e732e6f72672f67757a7a6c652f666636663631)](https://docs.guzzlephp.org/) [![Panther / Chrome](https://camo.githubusercontent.com/47e7838677b9bd800209ed23443b6e9e32a227dd1bc81e516d8c6afd9cbeb704/68747470733a2f2f63646e2e73696d706c6569636f6e732e6f72672f73656c656e69756d2f343342303241)](https://github.com/symfony/panther) [![Laravel](https://camo.githubusercontent.com/49c982934162722001bc7fa9529756889d31c4e9b0a33ef06370a09a153d2579/68747470733a2f2f63646e2e73696d706c6569636f6e732e6f72672f6c61726176656c2f464632443230)](https://laravel.com/)

Funcionalidades
---------------

[](#funcionalidades)

- **Estratégia automática** — o `StrategyResolver` escolhe entre cliente leve (Guzzle + Symfony DomCrawler) ou pesado (Symfony Panther / Chrome headless) conforme o adapter.
- **Adaptadores verificados** para os principais portais de emprego angolanos (ver tabela abaixo).
- **Modelos de dados flexíveis** — `Company` e `Job` com campos comuns + array `extra` para metadados específicos.
- **Autenticação** — suporte a cookies/headers de sessão para portais que exigem login.
- **Paginação** — seguimento automático de "próxima página" quando o adapter o indica.
- **Demo Bootstrap** — página de exemplo que corre os adapters e apresenta os resultados numa tabela.

Instalação
----------

[](#instalação)

```
composer require anilpedro07/scraper_vagas
```

Para usar a estratégia pesada (sites com JavaScript/Ajax):

```
composer require --dev symfony/panther
```

Início rápido
-------------

[](#início-rápido)

### Empresas (adapter genérico/configurável)

[](#empresas-adapter-genéricoconfigurável)

```
use AngolaEmpresas\Scraper\Scraper;
use AngolaEmpresas\Scraper\Adapters\GenericAdapter;

$adapter = new GenericAdapter(
    'https://exemplo.co.ao/empresas',
    'light',                 // ou 'heavy' para sites com JS
    [
        'list'    => '.empresa',
        'name'    => '.name',
        'phone'   => '.phone',
        'email'   => '.email',
        'website' => '.website',
        'address' => '.address',
        'province'=> '.province',
        'sector'  => '.sector',
        'nif'     => '.nif',     // campo extra vai para 'extra'
    ],
    ['source' => 'exemplo.co.ao'],
);

$scraper = new Scraper();
$companies = $scraper->scrape($adapter);

foreach ($companies as $company) {
    echo $company->name . ' -> ' . $company->phone . PHP_EOL;
    print_r($company->toArray());
}
```

### Vagas de emprego (adapter verificado)

[](#vagas-de-emprego-adapter-verificado)

```
use AngolaEmpresas\Scraper\Scraper;
use AngolaEmpresas\Scraper\Adapters\AngoEmpregoAdapter;

$jobs = (new Scraper())->scrapeOnce(new AngoEmpregoAdapter());
foreach ($jobs as $job) {
    echo $job->title . ' @ ' . $job->company . ' (' . $job->location . ')' . PHP_EOL;
}
```

Adaptadores verificados
-----------------------

[](#adaptadores-verificados)

Estes adapters foram testados e devolvem **dados reais**:

AdapterSiteEstratégiaAutenticação`AngoEmpregoAdapter`angoemprego.com (WP Job Manager)`light`não`AoEmpregosYoYotaAdapter`ao.empregosyoyota.net/empregos`light`não`JobartisAdapter`jobartis.com/vagas-emprego`light`cookie `_jobartis_session_1`Para o `JobartisAdapter` com sessão:

```
use AngolaEmpresas\Scraper\Adapters\JobartisAdapter;

$adapter = new JobartisAdapter(cookies: [
    '_jobartis_session_1' => 'VALOR_DO_COOKIE_COPIADO_DO_BROWSER',
]);
```

Portais que exigem login
------------------------

[](#portais-que-exigem-login)

Muitos portais só mostram as vagas após autenticação. Duas abordagens:

### 1) HTML estático atrás de sessão (estratégia `light`)

[](#1-html-estático-atrás-de-sessão-estratégia-light)

Copie os **cookies de sessão** (DevTools → Application → Cookies, ex.: `sessionid`, `PHPSESSID`) e devolva-os em `getAuth()`; o `LightClient` envia-os no pedido.

```
use AngolaEmpresas\Scraper\Adapters\AbstractJobAdapter;
use AngolaEmpresas\Scraper\Model\Job;

final class PortalAuthAdapter extends AbstractJobAdapter
{
    public function getStrategy(): string { return 'light'; }
    public function getUrl(): string     { return 'https://portal.co.ao/vagas'; }

    public function getAuth(): array
    {
        return [
            'cookies' => ['sessionid' => 'COOKIE_COPIADO_DO_BROWSER'],
            // ou: 'headers' => ['Authorization' => 'Bearer SEU_TOKEN'],
        ];
    }

    public function parse(string $html): array
    {
        $page = $this->crawl($html);
        return $page->filter('.vaga')->each(fn ($n) => new Job(
            title: $this->clean($this->text($n, '.titulo')),
            company: $this->clean($this->text($n, '.empresa')),
        ));
    }
}

$jobs = (new \AngolaEmpresas\Scraper\Scraper())->scrapeOnce(new PortalAuthAdapter());
```

### 2) Portal com JavaScript / login interativo (estratégia `heavy`)

[](#2-portal-com-javascript--login-interativo-estratégia-heavy)

```
use Symfony\Component\Panther\Client;

$client = Client::createChromeClient();
$client->get('https://portal.co.ao/login');
$client->submitForm('Entrar', ['username' => '...', 'password' => '...']);
$client->get('https://portal.co.ao/vagas');
$html = $client->getPageSource();
// passe $html ao adapter->parse($html)
```

> O LinkedIn bloqueia scraping e proíbe nos ToS — use a API oficial. Para qualquer portal, respeite `robots.txt` e os Termos de Serviço.

Criar o seu próprio adapter
---------------------------

[](#criar-o-seu-próprio-adapter)

```
use AngolaEmpresas\Scraper\Adapters\AbstractAdapter;
use AngolaEmpresas\Scraper\Model\Company;

final class MeuSiteAdapter extends AbstractAdapter
{
    public function getStrategy(): string { return 'light'; }
    public function getUrl(): string     { return 'https://meusite.co.ao'; }

    public function parse(string $html): array
    {
        $page = $this->crawl($html);
        return $page->filter('.empresa')->each(fn ($node) => new Company(
            name: $this->clean($this->text($node, '.nome')),
            phone: $this->clean($this->text($node, '.tel')),
        ));
    }
}
```

Demonstração (Bootstrap)
------------------------

[](#demonstração-bootstrap)

`demo/index.php` é uma página com Bootstrap que corre os adapters e apresenta os resultados numa tabela, com botão **"Ver mais"** por vaga (abre o site de destino). Suporta:

- `?mode=live` — scraping real (adapters `light`, com cookie para o Jobartis)
- `?mode=fixture` — offline, com HTML de exemplo em `demo/fixtures/`

```
php -S 127.0.0.1:8123 -t demo
# http://127.0.0.1:8123/            (ao vivo)
# http://127.0.0.1:8123/?mode=fixture
```

> A pasta `demo/` não é versionada (está no `.gitignore`).

Testes
------

[](#testes)

```
composer install
composer test
```

Roadmap
-------

[](#roadmap)

- Exemplo de integração **Laravel** (`examples/laravel-demo`): ServiceProvider, Artisan command, Eloquent model, agendamento e filas.
- Mais adaptadores verificados de portais angolanos.

Boas práticas
-------------

[](#boas-práticas)

- Respeite `robots.txt` e os Termos de Serviço de cada site.
- Adicione pausas (`sleep`) entre pedidos para não sobrecarregar os servidores.
- Não utilize os dados extraídos para spam ou violação de privacidade.

Licença
-------

[](#licença)

[MIT](LICENSE) © anilpedro07

###  Health Score

22

↑

LowBetter than 21% of packages

Maintenance65

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/6093135fb71905a3283ea0c3287273b2d66f618b5a7468e7dbb8962fb4e29e37?d=identicon)[anilpon-pedro](/maintainers/anilpon-pedro)

---

Top Contributors

[![anilp07x](https://avatars.githubusercontent.com/u/134443092?v=4)](https://github.com/anilp07x "anilp07x (4 commits)")

### Embed Badge

![Health badge](/badges/anilp07x-scraper-vagas/health.svg)

```
[![Health](https://phpackages.com/badges/anilp07x-scraper-vagas/health.svg)](https://phpackages.com/packages/anilp07x-scraper-vagas)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
