cobaia / marsvin
Marsvin 是一个用于编写爬虫应用的框架
v1.0.0
2013-01-21 05:32 UTC
Requires
- php: >=5.3.0
- evenement/evenement: 1.0.0
- kriswallsmith/buzz: 0.7
- kriswallsmith/spork: 0.1
- symfony/console: 2.1.*
This package is not auto-updated.
Last update: 2024-09-14 12:34:23 UTC
README
#Marsvin
这是什么?
你曾经编写过爬虫或解析器吗?
如果是,你肯定知道这总是一个简单的任务,但我们总是要思考如何构建代码来执行此类操作...
所以...为了解决这个问题,Marvins 被创建出来,Marvins 提供了一个简单的 API 和结构,供您创建自己的解析器或爬虫。主要关注的是简化从外部资源解析数据、从网站提取数据或从 XML、CSV 文件等导入数据的任务...
而且还有更多,作为额外功能,它还包含进程管理,这使得您能够同时打开多个 PHP 进程,因此您能够同时做很多事情。
如何使用它?
创建一个 composer.json
{ "name" : "your/projectname", "require" : { "cobaia/marsvin" : "dev-master" }, "minimum-stability" : "dev" }
运行以下命令
composer.phar install
创建您的控制台命令
文件: console.php
<?php require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use Symfony\Component\Console\Application; use Symfony\Component\Console\Helper\HelperSet; $console = new Application('Your Project', '1.0'); $console->addCommands( array( new Marsvin\Command\GenerateProviderCommand(), new Marsvin\Command\RequestProviderCommand(), ) ); //You are able to pass as much helper set you want, like Doctrine, Monolog, etc... //$console->setHelperSet($helperSet); $console->run();
创建控制台后,您已经可以运行以下命令:php app/console.php
您将检查我们有两个命令可以使用
marsvin marsvin:generate:provider Generate Provider code structure marsvin:request:provider Request one specific Provider
Marsvin 使用以下命名约定
- 提供者:这是您将要执行的操作的名称,例如,Facebook、Github、Google 等。
- 请求者:这是负责向提供者发起请求的层,例如,对于 Facebook,可能是 HTTP 请求,对于 Github,可能是一次 Git 操作,对于其他提供者,可能是 FTP 访问等。
- 解析器:一旦请求操作完成,解析器层就会进入,这一层将负责数据,所以如果您想设置 doctrine 的某些实体或创建数据数组等,或者您想以某种方式规范化数据,这就是您将使用的层来完成此类任务。
- 持久化器:一旦解析了数据,它就会进入持久化器层,在这里您可以对数据进行任何操作,例如,在 doctrine 中,您可以将数据持久化和刷新到数据库,或者如果您想将数据持久化到文件系统、发送电子邮件等,持久化器层将为您处理这些操作。
创建我们的第一个提供者
要创建我们的提供者,Marvins 提供了一个命令来为您创建文件夹结构
php app/console marsvin:generate:provider MyProject\\Github ./src/
您将检查 Marsvin 会为您生成以下文件夹树
.
└── MyProject
└── Github
├── GithubParser.php
├── GithubPersister.php
├── GithubProvider.php
└── GithubRequester.php
现在是时候设置适配器了,Marvins 使用适配器模式来定义每一层,例如,如果您想进行 HTTP 请求,您可以在请求者层设置一个 HttpAdapter 来使用。
默认情况下,Marvins 包含一些适配器
- 请求者:DefaultAdapter.php BuzzAdapter.php
- 解析器:DomAdapter.php
- 持久化器:DefaultAdapter.php DoctrineAdapter.php
因此,让我们设置我们的提供者
<?php namespace MyProject\Github; use Marsvin\Provider\AbstractProvider; use Marsvin\Provider\ProviderInterface; use Marsvin\Requester\Adapter\BuzzAdapter; use Marsvin\Parser\Adapter\DomAdapter; use Marsvin\Persister\Adapter\DefaultAdapter; class GithubProvider extends AbstractProvider implements ProviderInterface { public function getRequesterAdapter() { return new BuzzAdapter(); } public function getParserAdapter() { return new DomAdapter(); } public function getPersisterAdapter() { return new DefaultAdapter(); } }
请求者
<?php namespace MyProject\Github; use Marsvin\Requester\AbstractRequester; use Marsvin\Requester\RequesterInterface; use Marsvin\Response; class GithubRequester extends AbstractRequester implements RequesterInterface { const GITHUB_URL = 'https://github.com/%s?tab=repositories'; public function request() { $adapter = $this->getAdapter(); $profiles = array( 'krolow', 'gquental', 'moacirosa', 'fabpot', ); $self = $this; foreach ($profiles as $profile) { $this->process(function () use ($self, $adapter, $profile) { $self->done( new Response( $adapter->request( sprintf( GithubRequester::GITHUB_URL, $profile ) ) ) ); }); } } }
解析器
<?php namespace MyProject\Github; use Marsvin\Parser\AbstractParser; use Marsvin\Parser\ParserInterface; use Marsvin\Response; use Marsvin\ResponseInterface; use DOMXPath; use DOMDocument; class GithubParser extends AbstractParser implements ParserInterface { public function parse(ResponseInterface $response) { $adapter = $this->getAdapter(); $dom = $adapter->parse($response->get()); $xpath = new DOMXPath($dom); $nodes = $xpath->query('//span[@itemprop="name"]'); $author = $nodes->item(0)->nodeValue; $nodes = $xpath->query('//li[contains(@class, "public")]'); $projects = array(); foreach ($nodes as $node) { array_push( $projects, $this->parseProject($node, $author) ); } $this->done(new Response($projects)); } protected function parseProject($node, $author) { $doc = new DOMDocument(); $doc->appendChild($doc->importNode($node, true)); $name = $doc->getElementsByTagName('h3'); $url = $doc->getElementsByTagName('a'); $project = array( 'name' => trim($name->item(0)->nodeValue), 'url' => 'http://github.com/' . $url->item(2)->getAttribute('href'), 'author' => $author ); return $project; } }
持久化器
<?php namespace MyProject\Github; use Marsvin\Persister\AbstractPersister; use Marsvin\Persister\PersisterInterface; use Marsvin\Response; use Marsvin\ResponseInterface; class GithubPersister extends AbstractPersister implements PersisterInterface { public function persists(ResponseInterface $response) { $adapter = $this->getAdapter(); $adapter->persist($response->get()); file_put_contents('/tmp/marsvin.log', var_export($adapter->flush(), true), FILE_APPEND); } }
要运行命令,请执行以下操作
php app/console.php marsvin:request:provider MyProject\\Github\\GithubProvider
您可以通过以下方式检查这里正在发生什么
tail -f /tmp/marsvin.log