常见问题汇总


01、在哪里编写业务代码?

在每个应用的Start目录【/path/to/PHPCreeper-Application/Application/Spider/爬虫项目名称/Start/】下面列有不同的应用实例启动脚本, 这些脚本里分别对应有各自的onXXX业务回调,所以说除了基础的配置代码之外,所有的业务代码都是在onXXX回调里编写。

02、合理设计回调返回值有助于对付各种复杂应用场景

举个例子:比如使用无头浏览器回调API:

<?php
$downloader = new Downloader();
$downloader->onHeadlessBrowserOpenPage = function($downloader, $browser, $page, $url){
	//注意:灵活设计特定类型的返回值有助于对付各种复杂的应用场景
	//1. 返回false, 会触发中断后续的业务逻辑;
	//2. 返回string,会触发中断后续的业务逻辑,一般多用于返回页面的HTML;
	//3. 返回array, 会继续执行后续的业务逻辑,一般多用于返回无头浏览器选项参数;
	//4. 返回其他,  会继续执行后续的业务逻辑,相当于是什么也没有发生;

	//注意:一般无需调用如下几行代码,因为爬山虎内部默认会自动调用无头API做同样的工作.
	//$page->navigate($url)->waitForNavigation('firstMeaningfulPaint');
	//$html = $page->getHtml();
	//return $html;
};

03、是否可以脱离爬山虎应用框架进行自由定制开发?

当然可以,PHPCreeper-Application【即爬山虎应用框架】类似于传统的MVC框架的意义,主要是方便开发者进行敏捷开发,所以说这个框架并不是必须的,不过作者推荐使用爬山虎应用框架进行开发,相对更加快捷高效;当然啦,开发者也完全可以单独引入爬山虎引擎,即脱离爬山虎应用框架进行自由定制开发,一样简单高效。

04、如何脱离爬山虎应用框架进行自由定制开发?

请参考第5.2章节离框开发

05、如何发送 application/x-www-form-urlencoded 类型的POST表单请求?

<?php
$producer = new Producer();
$producer->onProducerStart = function($producer){
    $context['form_params'] = [
        'name1' => 'value1',
        'name2' => 'value2',
    ];

    $task = [
        'url'     => 'http://yourdomain.com/post',
        'method'  => 'post',
        'context' => $context,
    ];

    $producer->createTask($task);
};

06、如何发送 multipart/form-data 类型的POST表单请求?

注意:contents 字段的类型任何时候都只能是字符串,如果希望contents表达的是流数据,那么需要新增配置字段contents_as_streamtrue,这样就相当于启用了文件上传功能。

<?php
$producer = new Producer();
$producer->onProducerStart = function($producer){
    $context['multipart'] = [
		[
			'name'     => 'k1',
			'contents' => 'v1',
		],
		[
			'name'     => 'k2',
			'contents' => '/path/to/file',
			'contents_as_stream' => true,
			'filename' => 'custom_filename.txt'
		],
    ];

    $task = [
        'url'     => 'http://yourdomain.com/post',
        'method'  => 'post',
        'context' => $context,
    ];

    $producer->createTask($task);
};

07、如何设置http请求头?

主要用途之一就是浏览器伪装,默认引擎会自动伪装成各种常见的随机User-Agent,有两种设置方法:
【注意:如果同时使用了两种方法,则API接口的优先级高于context配置,即高者会覆盖低者配置】

方法一:通过context上下文配置实现

<?php
$context['headers'] = [
    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
    'Accept'     => 'text/html,*/*;',
];

方法二:通过API接口实现

<?php
$downloader = new Downloader();
$downloader->onBeforeDownload = function($downloader, $task){
    //注意 setHeaders() 方法同时支持数组和字符串类型的参数,
    //一般从fiddler或charles软件直接复制头字符串粘贴过来即可.
    $downloader->httpClient->setHeaders([
        'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
        'Accept'     => 'text/html,*/*;',
    ]);
};

08、无头浏览器常用的配置参数

配置项默认值备注说明
headlesstrue要不要启用无头模式
noSandboxtrue要不要禁用sandbox模式,在docker容器中运行时有用
keepAlivefalse要不要在脚本终止时保活即不杀死chrome子进程
sendSyncDefaultTimeout10000发送同步消息的默认超时(单位:毫秒)
headersnone自定义HTTP请求头数组
userAgentnone设置浏览器的User-Agent
enableImagestrue要不要加载图片
customFlagsnone要传递给无头浏览器的自定义参数数组。例如:['--option1', '--option2=someValue']
debugLoggernull设置用于打印调试消息的组件。例如:"php://stdout"
disableNotificationsfalse要不要禁用浏览器通知
ignoreCertificateErrorstrue将Chrome设置为忽略SSL错误
noProxyServerfalse不要使用代理服务器,始终进行直连。
proxyServernone使用代理服务器,例如: 127.0.0.1:8080
proxyBypassListnone绕过代理设置并使用直接连接的主机列表
startupTimeout30等待Chrome启动的最长时间(单位:秒)
userDataDirnoneChrome用户数据目录(默认临时生成一个新空目录)

09、关于无头回调API使用注意事项

  • 爬山虎默认会使用内部的无头API来自动完成无头浏览任务,同时也可以劫持无头回调API onHeadlessBrowserOpenPage 来完成类似的任务, 但是注意如果项目中没有使用此无头回调API,建议最好注释或删除本回调API的定义代码。

  • 无头浏览器的配置参数 keepAlive 的值强烈建议配置为 false,否则爬山虎组件进程退出后可能会引起意外的chrome子进程总数持续增长的问题。

  • 无头浏览器的配置参数和普通的httpClient的配置参数不是共享的,即无头浏览器的配置参数是独有的,见本节表格-08段说明。

Free Web Hosting