关于PHP批量采集----采集小说站有感

概况:帮周同窗作小说采集作了有一段时间了。一开始是从其它网站的页面上直接写正则去采集,而后慢慢的转为采集别人提供的API。 ajax

环境:CENTOS+NGINX+PHP5.2.17。基于JIEQI小说管理系统。 数组

直接采集其它网站页面的时候,主要改的是JIEQI自带的采集系统,印象比较深的,是加上了判断章节顺序的功能,还修改了其它的“BUG”(呀,其它具体什么来着,我如今都快忘了,作了很久了)。这回感触比较深的是,是采集API。 服务器

背景:采集数十个小说站的API(目前有五个,预计有40,50个) 异步

设计:共用一个显示页面,逻辑分开处理。可批量采集,可单篇采集。 优化

上个图:其中,两个实体,是根据我须要的信息,本身定义的。为何要规定这个实体(或者是接口),主要是由于,每一个API给的信息都是不同的,要统一后,才能操做。 网站

单篇采集 VS 多篇采集 spa

单篇采集相对比较简单,想怎么写都行,问题不大。 .net

而多篇批量采集,此次写了四个版本。 线程

V1:将全部的操做,写在了同一PHP进程里面。 设计

    优点:逻辑简单,容易实现。

    缺点:PHP进程容易庞大,容易挂悼。

    问题:最大只能设置5篇,并且,不能看到采集的过程。

V2:将全部的操做分开,用file_get_contents遍历访问。

    优点:相似“异步”采集,将全部操做分开到每一个进程,单进程不容易挂。效率很高。

    缺点:采集过程将产生N多个PHP进程,NGINX会出现504等错误。

    问题:如上述缺点,若是一做品的章节较多,在短期内(0.1S或更短)产生上百个HTTP请求,NGINX出现问题,服务器吃不消。

    改进:在PHP中加上sleep,致使NGINX不稳定,集中耗资源。偶尔还出现file_get_contents的错误。

V3:结合V1和V2,用JS作定时。

    思路:使用iframe,定时刷新采集的每一个页面(V2),根据页面返回信息,作下一步操做。即:循环设置iframe的SRC。

    优点:将采集时集中对服务器的压力分散掉,章节按顺序来入库。

    缺点:采集的间隔时间,不太好设置。哪怕是根据iframe的返回值,再判断,也要多加定时(采用父页面定时刷新,定时抓取iframe的数据来判断)。

    问题:setTimeout出各类问题,会出现没法控制的状况。由于JS也是单线程的。setInertval也同样。

V4:结合前面三,主要改进是在V3的基础上,再次分开。

    思路:再也不循环设置iframe的SRC,而是,新建N多个iframe。

    优点:能够很轻松的控制时间(即:间隔多少S,打开新的iframe)。

    缺点:若前面的章节操做比较慢(即:好比说,第一章卡壳了,2S都尚未链接上采集的PHP的URL。而第二章,在第0.5S后,已经开始,且链接上了,那么第二章就会在第一章以前入库),这里就涉及到一个章节的顺序问题。还有,同上,第一章已经链接上了,但,操做特慢,2S才搞定;而第二章,字数少(或其它缘由),1S就搞定了,问题同上。

    问题:同上缺点所述,还有一个问题要注意。由于有些字段,必需要在采集完以后,更新表的。SO,采用了一个方法:就是子页JS,调用父页的JS的一个方法,在父页中设置一个iframe(ajax或script同样),访问修正做品的URL。

    实用:果真,实用的时候,缺点所产生的问题已经出现了。

    修正:将章节排序的字段,作到和章节信息同样,放到数组里面,同步更新。这样,哪怕第二章先入库,但它的order,仍是2。第一章后入库,其order为1。在显示时,仍是第一章在前面。问题解决。

    

    每一个采集站的API和模版都分开了,这样的好处就是统一了接口,其它的自由发挥。作这个玩意,也被周同窗说了几回,不过想一想,确实,一开始作的时候,没有考虑这么细,作得不够好,看来,仍是经验不够啊。

    固然,采集的话,建议使用.net作成一个EXE。有向周同窗提,但他以为更麻烦,也懒得从新来弄过。如今这个版本,够用了,符合要求了。还有优化的地方继续优化。

    此抛砖引玉,期待大牛们的指点。

相关文章
相关标签/搜索