常见问题汇总
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_stream
为true
,这样就相当于启用了文件上传功能。
<?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、无头浏览器常用的配置参数
配置项 | 默认值 | 备注说明 |
---|---|---|
headless | true | 要不要启用无头模式 |
noSandbox | true | 要不要禁用sandbox模式,在docker容器中运行时有用 |
keepAlive | false | 要不要在脚本终止时保活即不杀死chrome子进程 |
sendSyncDefaultTimeout | 10000 | 发送同步消息的默认超时(单位:毫秒) |
headers | none | 自定义HTTP请求头数组 |
userAgent | none | 设置浏览器的User-Agent |
enableImages | true | 要不要加载图片 |
customFlags | none | 要传递给无头浏览器的自定义参数数组。例如:['--option1', '--option2=someValue'] |
debugLogger | null | 设置用于打印调试消息的组件。例如:"php://stdout" |
disableNotifications | false | 要不要禁用浏览器通知 |
ignoreCertificateErrors | true | 将Chrome设置为忽略SSL错误 |
noProxyServer | false | 不要使用代理服务器,始终进行直连。 |
proxyServer | none | 使用代理服务器,例如: 127.0.0.1:8080 |
proxyBypassList | none | 绕过代理设置并使用直接连接的主机列表 |
startupTimeout | 30 | 等待Chrome启动的最长时间(单位:秒) |
userDataDir | none | Chrome用户数据目录(默认临时生成一个新空目录) |
09、关于无头回调API使用注意事项
-
爬山虎默认会使用内部的无头API来自动完成无头浏览任务,同时也可以劫持无头回调API
onHeadlessBrowserOpenPage
来完成类似的任务, 但是注意如果项目中没有使用此无头回调API,建议最好注释或删除本回调API的定义代码。 -
无头浏览器的配置参数
keepAlive
的值强烈建议配置为false
,否则爬山虎组件进程退出后可能会引起意外的chrome子进程总数持续增长的问题。 -
无头浏览器的配置参数和普通的httpClient的配置参数不是共享的,即无头浏览器的配置参数是独有的,见本节
表格-08
段说明。