首页 » PHP教程 » php应用phpwebdriver技巧_php 的爬虫经验分享

php应用phpwebdriver技巧_php 的爬虫经验分享

访客 2024-11-18 0

扫一扫用手机浏览

文章目录 [+]

入职冰鉴科技做爬虫开拓已经半年多了,陆续开拓掩护了几个爬虫往后终于在 web 端爬虫这一块有了登堂入室的觉得。
中间踩了许多坑,也对爬虫的许多细节有了自己的认识,以是本日希望能分享一些爬虫履历。
虽然爬虫的很多东西不好说太细,由于说太细了别人立时有针对性的反爬虫了,而且很多技巧业界没用通用的办理方案(别人就举措看成出来了也不太乐意分享),都是我自己逐步摸索出来的。
但是我认为适当的业界 /友商之间的技能互换是必要的,不能闭门造车,我也渴望能和业界 /友商有更多私下的深入互换,大家多切磋才能进步嘛。
最近我在研究 app 反编译爬虫干系的,以是对这块特殊感兴趣。
个人博客: qsalg.com

为什么是 PHP

php应用phpwebdriver技巧_php 的爬虫经验分享

实在就目前业界来说, python 下的爬虫轮子是最多的,我厂大多数同学都用 python 搞爬虫。
我由于原来搞 web 后端用 PHP 比较多,对 PHP 下的生态和第三方库啥的如数家珍,厂里对利用的措辞也不做逼迫哀求,以是我就用最拿手的 PHP 开搞了。
有同学可能会以为 PHP 下爬虫轮子彷佛不多,乃至有部分做惯了 PHP 后台的同学在须要完成爬虫任务时也拿起了 python ,难道 PHP 就不适宜搞爬虫么?我认为正好相反, PHP 在 web 领域积累了大量成熟的第三方库,而且其强大的内容处理能力使之在须要噜苏处理的爬虫任务中如鱼得水。
爬虫从运行韶光上大致可以分为两种: 1 、实时的爬虫:一个要求来了我就开一个爬虫去爬取结果,一样平常情形下这种爬虫直接对外供应 API ; 2 、长期爬虫:这种爬虫一样平常会一贯运行或者定期运行,把数据更新入库。
一样平常来说这 2 种爬虫都须要比较频繁的掩护更新, PHP 作为一门支配大略的脚本措辞,可以履行热更新爬虫代码,非常方便。

php应用phpwebdriver技巧_php 的爬虫经验分享
(图片来自网络侵删)

利用第三方库

用 PHP 搞爬虫请利用好 composer 下的第三方库。
PHP 在 web 领域积累了大量成熟的第三方库,基本上你想得到的库都能在 github 上都能找到,如果你不用第三方库的话,那么你就即是放弃了 PHP 在 web 领域的巨大上风。
爬虫干系的 PHP 第三方库我用的比较多的有:

1 、 Guzzle :功能很完善的 httpclient ,带异步并发功能,别的脚本措辞找不到这么好的 httpclient

2 、 Goutte :对 symfony 的 dom-crawler 和 css-selector 的大略封装,你也可以直接用 symfony 的 css-selector 来抽取 html 的 dom 元素

3 、 symfony/process : symfony 出品的 php 开进程的库(封装的 proc_open ),兼容 windows ,要知道 pcntl 扩展不支持 windows 的

4 、 php-webdriver : Facebook 官方掩护的 selenium 的 php 客户端

前段韶光有一个《我用爬虫一天韶光“偷了”知乎一百万用户,只为证明 PHP 是天下上最好的措辞》,这个 repo 很受关注也一贯在掩护。
我也研究了一下他的代码,质量很高,但是有一个缺陷便是没有利用现有的第三方库而选择自己封装。
我们该当把精力花在爬虫业务上而不是去重新造轮子,我平时直接无脑的利用现有的 composer 下的各种第三方库。
我从今年 4 月份入职到现在 8 个月韶光只写了 3 个爬虫(除了爬虫业务外,基于 redis 的分布式爬虫调度、单机多爬虫并发、报警+监控+参数掌握、 selenium 多浏览器匹配+特性定制、代理策略定制 and so on )一套下来,所有代码都加起来只有 6000 行 PHP 代码。
已经有现成的成熟稳定的第三方库不用,自己造轮子是得不偿失落的。

多线程、多进程和异步

爬虫不能不说到并发,爬虫作为一个 IO 密集型而不是 CPU 密集型的任务,一个好的并发的爬虫该当知足: 1 、只管即便可能高的下载带宽(下载带宽越高,爬的数据越多); 2 、尽可能小的 CPU 花费和尽可能小的内存花费。
多线程彷佛是实现并发的不错的办法,常常有人说“ PHP 没有多线程”让广大 PHPer 直不起腰。
作为 web 后真个时候 PHP 没法利用多线程,但是作为命令走运行的话 PHP 是支持多线程的。
我们知道 PHP 分为线程安全( ZTS )和非线程安全版本( NTS ),后者实在是为了兼容 win 下 IIS 的 ISAPI ,这也就逼着 PHP 下的扩展基本上都供应的线程安全和非线程安全版本。
也便是说从理论上来说命令行的 PHP 多线程是真的多线程,没有像 py 或者 ruby 那样的全局锁(实际上同一时候只有一个线程在跑),但是实际上 PHP 命令行多线程不太稳定(毕竟它的多线程不是为 php-cli 设计的),以是我建议命令行运用还是利用多进程来做并发。
而异步也是实现并发的主要方法,爬虫须要并发的大多数情形是我想是同时去爬多个 url ,这种情形无须利用多进程 /多线程,直接在单进程中利用异步就可以了。
比如 PHP 的 Guzzle 异步支持非常好用, Guzzle 默认异步是包装的 curl 的 curl_multi 的几个函数来做的,如果你想用性能更好的异步事宜库可以设置 Guzzle 的 adapter 为 react-guzzle-psr7 (当然了你得安装 Event 之类的异步 pecl 扩展)。
我个人试用下来以为 Guzzle 默认的异步就够用了,单进程并发几十上百的 http 要求跑满小水管那是不成问题的, cpu 和内存花费还很小。
总之,把 php 的多进程和异步合起来用,实现良好的并发不是问题。

关于爬虫框架

开箱即用封装好的爬虫框架不是银弹。
我一开始也研究了 java 和 py 下的一些比较著名的框架,企图先把这些框架学会然后把自己的爬虫任务整合进去,后来创造这么做很困难。
诚然用爬虫框架基本上改两行就可以跑起来了,对大略的爬虫任务来说很不错。
但是用别人封装好的框架会导致爬虫的定制性变差(要知道爬虫是须要灵巧处理各种情形的),而我们知道爬虫的实质便是开着 httpclient 取回 html 然后 dom 抽取数据就完了(并发的话再加个多进程管理),就这么大略的任务为了尽可能知足所有人须要被封装成了一个繁芜系统的框架,并不一定适宜所有的情形。
有一次 V2EX 上也有人出来质疑说我直接用 requests 也很大略啊, scrapy 的上风在哪里呢?我的理解是爬虫框架的上风就在于把爬虫的并发调度都做了,而我们直接单进程来写爬虫的话只能是一个单进程爬虫没有并发调度。
实在爬虫的多进程并发调度没那么繁芜,也不须要搞太繁芜,我说说我的 php 爬虫是怎么做并发调度的( python 下一回事)。

爬虫多进程调度

我的 PHP 爬虫多进程调度比较大略粗暴,爬虫分为管理爬虫进程的 Master 进程和卖力详细爬取业务的 worker 进程,而 redis 卖力对爬虫进行掌握以及显示爬虫的状态。

比如我有一个爬取 A 站点的爬虫任务,我开拓好爬虫 Worker A 往后,我可以在 redis 中设置在做事器 Node1 上我开 2 个 Worker A 来爬,而 Node1 上的 master1 进程会定期去 redis 中读取掌握参数,如果创造 Node1 上的 Worker A 进程不敷 2 个的话就会新开 Worker A 进程补充。
当然了,掌握参数须要包含哪些你可以自己定制,比如我就定制了每个节点的 Worker 上限、利用的代理策略、是否禁止加载图片、浏览器特性定制等等。
Master 进程新开 Worker 进程有 2 种办法,一种是通过类 exec (比如在 Master 进程中 proc_open(‘ php Worker.php balabala ’, $descriptorspec, $pipes)这样)调用来开一个新的命令行 php 的 Worker 进程,其余便是通过 fork 机制来做。
我采取了类 exec 调用的方法(实在是 symfony/process 库,它封装的 proc_open 函数来开的进程)来开 Worker 进程(如果要传命令行参数给 Worker 进程把稳利用 base64 编码一下,由于命令行可能会过滤某些参数),这么做的好处便是解耦。
须要把稳的是,现在 Worker 进程都是 Master 进程的子进程,以是 Master 进程退出的话所有 Worker 进程也会退出,以是 Master 进程把稳非常的 catch ,尤其是 redis 、数据库和别的有网络 io 的地方。
如果你希望 Worker 进程 damonize 的话请按这篇文章的方法来( php 下也是一样的,不过不兼容 windows )。
我不建议 Master 进程通过 IPC 机制对 Worker 进程进行掌握,由于这么做一下子就让 Master 进程和 Worker 进程耦合起来了, Master 进程该当只是大略的卖力开 Worker 进程而已。
对 Worker 进程的掌握可以通过 Redis 来完成,也便是说 Worker 进程每隔一段韶光(可以是完成了一次 http 要求,或者每隔几秒)可以去 Redis 读一次掌握参数(如果须要的话,也可以到申报请示一下自己状态,参数比较多的话用好 redis 的 pipeline ),在实践中这种方法事情的很好。
我的 PHP 爬虫中都采取了这个大略粗暴的方案,我认为它的好处有 4 个:

1 、支持分布式且依赖大略,参数掌握+状态申报请示直接通过单一的 redis 节点。
我推举你用一个好的 redis 的 GUI 工具来管理 redis , redis 的 5 种数据构造用来做爬虫参数掌握+爬虫状态显示非常方便

2 、 Master 进程和 Worker 进程解耦,而且可以办理爬虫较多发生的内存泄露问题( Worker 进程跑完直接退出),也可以热更新代码

3 、实时爬虫可以通过 Master 进程抢占 push 到 redis list 中的要求来做,而长期任务的爬虫在 Worker 进程意外退出后 Master 进程急速补充,能适应各种爬虫任务

4 、开拓爬虫只用去写 Worker 进程就 ok 了,开拓方便,不用关心调度问题

缺陷当然便是这一套机制都须要你自己写,高度可定制性的代价便是自己动手。

总结

把我的 PHP 下爬虫履历的几个方面拿出来讲了一下,由于篇幅有限 Selenium 干系的履历就留到下次再说了。

以上

标签:

相关文章

执业药师试卷代码解码药师职业发展之路

执业药师在药品质量管理、用药安全等方面发挥着越来越重要的作用。而执业药师考试,作为进入药师行业的重要门槛,其试卷代码更是成为了药师...

PHP教程 2025-02-18 阅读1 评论0

心灵代码主题曲唤醒灵魂深处的共鸣

音乐,作为一种独特的艺术形式,自古以来就承载着人类情感的表达与传递。心灵代码主题曲,以其独特的旋律和歌词,唤醒了无数人的灵魂深处,...

PHP教程 2025-02-18 阅读1 评论0

探寻福建各市车牌代码背后的文化内涵

福建省,地处我国东南沿海,拥有悠久的历史和丰富的文化底蕴。在这片充满魅力的土地上,诞生了许多具有代表性的城市,每个城市都有自己独特...

PHP教程 2025-02-18 阅读1 评论0

探寻河北唐山历史与现代交融的城市之光

河北省唐山市,一座地处渤海之滨,拥有悠久历史和独特文化的城市。这里既是古丝绸之路的起点,也是中国近代工业的发源地。如今,唐山正以崭...

PHP教程 2025-02-18 阅读1 评论0