这个包提供了一个类来抓取网站上的链接。在底层,Guzzle Promise 用于同时抓取多个 url。
因为爬虫可以执行JavaScript,所以它可以爬行JavaScript渲染的网站。在底层,Chrome 和 Puppeteer 用于支持此功能。
我们投入了大量资源来创建一流的开源包。您可以通过购买我们的一款付费产品来支持我们。
我们非常感谢您从家乡寄给我们一张明信片,并注明您正在使用我们的哪种套餐。您可以在我们的联系页面上找到我们的地址。我们在虚拟明信片墙上发布所有收到的明信片。
这个包可以通过 Composer 安装:
作曲家需要空间/爬虫
爬虫可以这样实例化
使用 SpatieCrawlerCrawler; 爬虫::create() ->setCrawlObserver(<扩展 SpatieCrawlerCrawlObserversCrawlObserver 的类>) ->startCrawling($url);
传递给setCrawlObserver
参数必须是扩展SpatieCrawlerCrawlObserversCrawlObserver
抽象类的对象:
命名空间 SpatieCrawlerCrawlObservers;使用 GuzzleHttpExceptionRequestException;使用 PsrHttpMessageResponseInterface;使用 PsrHttpMessageUriInterface;抽象类 CrawlObserver {/* * 当爬虫抓取url时调用。 */公共函数 willCrawl(UriInterface $url, ?string $linkText): void{ }/* * 当爬虫成功抓取给定的url时调用。 */爬取的抽象公共函数(UriInterface $url,ResponseInterface $response, ?UriInterface $foundOnUrl = null, ?字符串$linkText, ): void;/* * 当爬虫在爬取给定的 url 时遇到问题时调用。 */抽象公共函数crawlFailed(UriInterface $url,RequestException $requestException, ?UriInterface $foundOnUrl = null, ?字符串 $linkText = null, ): void;/** * 爬网结束时调用。 */公共函数finishedCrawling(): void{ } }
您可以使用setCrawlObservers
设置多个观察者:
爬虫::create() ->setCrawlObservers([ <扩展 SpatieCrawlerCrawlObserversCrawlObserver 的类>, <扩展 SpatieCrawlerCrawlObserversCrawlObserver 的类>, ... ]) ->startCrawling($url);
或者,您可以使用addCrawlObserver
一一设置多个观察者:
爬虫::create() ->addCrawlObserver(<扩展 SpatieCrawlerCrawlObserversCrawlObserver 的类>) ->addCrawlObserver(<扩展 SpatieCrawlerCrawlObserversCrawlObserver 的类>) ->addCrawlObserver(<扩展 SpatieCrawlerCrawlObserversCrawlObserver 的类>) ->startCrawling($url);
默认情况下,爬虫不会执行JavaScript。这是启用 JavaScript 执行的方法:
爬虫::create() ->执行JavaScript() ...
为了能够在执行完 javascript 后获取正文 html,这个包依赖于我们的 Browsershot 包。这个包在底层使用了 Puppeteer。以下是有关如何在系统上安装它的一些提示。
Browsershot 将对其依赖项安装在系统上的位置进行有根据的猜测。默认情况下,Crawler 将实例化一个新的 Browsershot 实例。您可能会发现需要使用setBrowsershot(Browsershot $browsershot)
方法设置自定义创建的实例。
爬虫::create() ->setBrowsershot($browsershot) ->执行JavaScript() ...
请注意,即使您没有 Browsershot 所需的系统依赖项,爬网程序仍然可以工作。仅当您调用executeJavaScript()
时才需要这些系统依赖项。
您可以使用setCrawlProfile
函数告诉爬虫不要访问某些网址。该函数需要一个扩展SpatieCrawlerCrawlProfilesCrawlProfile
的对象:
/* * 确定是否应该抓取给定的url。 */公共函数shouldCrawl(UriInterface $url): bool;
该软件包附带三个开箱即用的CrawlProfiles
:
CrawlAllUrls
:此配置文件将抓取所有页面上的所有 url,包括外部站点的 url。
CrawlInternalUrls
:此配置文件只会抓取主机页面上的内部 URL。
CrawlSubdomains
:此配置文件只会抓取主机页面上的内部 URL 及其子域。
您可以通过将自定义UrlParser
传递给爬网程序来自定义从页面提取链接的方式。
爬虫::create() ->setUrlParserClass(<实现 SpatieCrawlerUrlParsersUrlParser 的类>::class) ...
默认情况下,使用LinkUrlParser
。该解析器将从a
的href
属性中提取所有链接。
还有一个内置的SitemapUrlParser
可以从站点地图中提取和抓取所有链接。它确实支持站点地图索引文件。
爬虫::create() ->setUrlParserClass(SitemapUrlParser::class) ...
默认情况下,爬虫将尊重机器人数据。可以像这样禁用这些检查:
爬虫::create() ->忽略机器人() ...
机器人数据可以来自robots.txt
文件、元标记或响应标头。有关该规范的更多信息,请访问:http://www.robotstxt.org/。
解析机器人数据是由我们的包 spatie/robots-txt 完成的。
默认情况下,爬虫会拒绝所有包含属性 rel="nofollow" 的链接。可以像这样禁用这些检查:
爬虫::create() ->接受NofollowLinks() ...
为了遵守自定义用户代理的 robots.txt 规则,您可以指定您自己的自定义用户代理。
爬虫::create() ->setUserAgent('我的代理')
您可以在 robots.txt 中为“my-agent”添加特定的抓取规则组。此示例不允许对“my-agent”标识的爬网程序爬网整个站点。
// 禁止抓取 my-agent 用户代理:我的代理 禁止:/
为了提高抓取速度,该包默认同时抓取 10 个 url。如果您想更改该数字,可以使用setConcurrency
方法。
爬虫::create() ->setConcurrency(1) // 现在所有的url都会被一一抓取
默认情况下,爬网程序会继续爬网,直到爬完它能找到的每个页面。如果您在有限制的环境(例如无服务器环境)中工作,此行为可能会导致问题。
可以使用以下两个选项来控制爬网行为:
爬网总数限制( setTotalCrawlLimit
):此限制定义要爬网的 URL 的最大数量。
当前抓取限制( setCurrentCrawlLimit
):这定义了当前抓取期间处理的 URL 数量。
让我们看一些示例来阐明这两种方法之间的区别。
setTotalCrawlLimit
方法允许您限制要爬网的 URL 总数,无论您调用爬网程序的频率如何。
$queue = <您选择/实现的队列>;// 抓取 5 个 URL 并结束。Crawler::create() ->setCrawlQueue($队列) ->设置TotalCrawlLimit(5) ->startCrawling($url);// 达到总限制后不再继续爬行。Crawler::create() ->setCrawlQueue($队列) ->设置TotalCrawlLimit(5) ->startCrawling($url);
setCurrentCrawlLimit
将设置每次执行抓取的 UR 数量的限制。这段代码每次执行将处理 5 个页面,没有爬行页面总数的限制。
$queue = <您选择/实现的队列>;// 抓取 5 个 URL 并结束。Crawler::create() ->setCrawlQueue($队列) ->设置CurrentCrawlLimit(5) ->startCrawling($url);// 抓取接下来的5个URL并结束.Crawler::create() ->setCrawlQueue($队列) ->设置CurrentCrawlLimit(5) ->startCrawling($url);
这两个限制可以结合起来控制爬虫:
$queue = <您选择/实现的队列>;// 抓取 5 个 URL 并结束。Crawler::create() ->setCrawlQueue($队列) ->设置总抓取限制(10) ->设置CurrentCrawlLimit(5) ->startCrawling($url);// 抓取接下来的5个URL并结束.Crawler::create() ->setCrawlQueue($队列) ->设置总抓取限制(10) ->设置CurrentCrawlLimit(5) ->startCrawling($url);// 达到总限制后不再继续爬行。Crawler::create() ->setCrawlQueue($队列) ->设置总抓取限制(10) ->设置CurrentCrawlLimit(5) ->startCrawling($url);
您可以使用setCurrentCrawlLimit
来中断长时间运行的爬网。以下示例演示了一种(简化的)方法。它由初始请求和任意数量的继续爬网的后续请求组成。
要开始跨不同请求进行爬网,您需要为所选队列驱动程序创建一个新队列。首先将队列实例传递给爬虫。当页面被处理并发现新的 URL 时,爬虫将开始填充队列。爬网程序完成后序列化并存储队列引用(使用当前爬网限制)。
// 使用您的队列驱动程序创建一个队列。$queue = <您对队列的选择/实现>;// 抓取第一组 URLsCrawler::create() ->setCrawlQueue($队列) ->设置当前抓取限制(10) ->startCrawling($url);// 序列化并存储你的队列$serializedQueue = serialize($queue);
对于以下任何请求,您需要反序列化原始队列并将其传递给爬虫:
// 反序列化队列$queue = unserialize($serializedQueue);// 抓取下一组URLsCrawler::create() ->setCrawlQueue($队列) ->设置当前抓取限制(10) ->startCrawling($url);// 序列化并存储你的队列$serialized_queue = serialize($queue);
该行为基于队列中的信息。仅当在行为中传递相同的队列实例时,行为才按所述工作。当传入一个全新的队列时,先前抓取的限制(即使对于同一网站)将不适用。
可以在此处找到包含更多详细信息的示例。
默认情况下,爬网程序会继续爬网,直到爬网完所提供 URL 的每个页面。如果你想限制爬虫的深度,你可以使用setMaximumDepth
方法。
爬虫::create() ->设置最大深度(2)
大多数 html 页面都很小。但爬虫程序可能会意外抓取 PDF 和 MP3 等大文件。为了在这种情况下保持较低的内存使用量,爬网程序将仅使用小于 2 MB 的响应。如果在流式传输响应时,它变得大于 2 MB,爬网程序将停止流式传输响应。将假定响应正文为空。
您可以更改最大响应大小。
// 让我们使用最大 3 MB.Crawler::create() ->设置最大响应大小(1024 * 1024 * 3)
在某些情况下,如果爬行过于激进,您可能会受到速率限制。为了避免这种情况,您可以使用setDelayBetweenRequests()
方法在每个请求之间添加暂停。该值以毫秒表示。
爬虫::create() ->setDelayBetweenRequests(150) // 每爬完一个页面,爬虫都会等待150ms
默认情况下,将下载每个找到的页面(大小最多为setMaximumResponseSize()
)并解析其他链接。您可以通过使用允许的类型数组设置setParseableMimeTypes()
来限制应下载和解析的内容类型。
爬虫::create() ->setParseableMimeTypes(['text/html', 'text/plain'])
这将防止下载具有不同 MIME 类型的页面正文,例如二进制文件、音频/视频……不太可能嵌入链接。此功能主要节省带宽。
当抓取网站时,抓取工具会将要抓取的 URL 放入队列中。默认情况下,该队列使用内置的ArrayCrawlQueue
存储在内存中。
当站点非常大时,您可能希望将该队列存储在其他地方,也许是数据库。在这种情况下,您可以编写自己的抓取队列。
有效的爬网队列是实现SpatieCrawlerCrawlQueuesCrawlQueue
接口的任何类。您可以通过爬虫上的setCrawlQueue
方法传递自定义爬网队列。
爬虫::create() ->setCrawlQueue(<SpatieCrawlerCrawlQueuesCrawlQueue的实现>)
这里
数组抓取队列
RedisCrawlQueue(第三方包)
Laravel 的 CacheCrawlQueue(第三方包)
Laravel 模型作为队列(第三方示例应用程序)
默认情况下,如果没有,爬虫会将基本 url 方案设置为http
。您可以使用setDefaultScheme
更改它。
爬虫::create() ->setDefaultScheme('https')
请参阅变更日志以了解最近更改的更多信息。
详细信息请参阅贡献。
首先,安装 Puppeteer 依赖项,否则您的测试将失败。
npm install puppeteer
要运行测试,您必须首先在单独的终端窗口中启动包含的基于节点的服务器。
cd 测试/服务器 npm 安装 节点服务器.js
服务器运行后,您可以开始测试。
作曲家测试
如果您发现有关安全的错误,请发送邮件至 [email protected],而不是使用问题跟踪器。
您可以自由使用这个软件包,但如果它进入您的生产环境,我们非常感谢您从您的家乡给我们寄一张明信片,注明您正在使用我们的哪个软件包。
我们的地址是:Spatie, Kruikstraat 22, 2018 安特卫普, 比利时。
我们在公司网站上发布所有收到的明信片。
弗里克·范德赫滕
所有贡献者
麻省理工学院许可证 (MIT)。请参阅许可证文件以获取更多信息。