Login
网站首页 > 文章中心 > 其它

php爬虫采集数据并发执行问题

作者:小编 更新时间:2023-08-02 08:17:19 浏览量:365人看过

如何提高爬虫效率

提高爬虫效率的方法

协程.采用协程,让多个爬虫一起工作,可以大幅度提高效率.

多进程.使用CPU的多个核,使用几个核就能提高几倍.

多线程.将任务分成多个,并发(交替)的执行.

分布式爬虫.让多个设备去跑同一个项目,效率也能大幅提升.

打包技术.可以将python文件打包成可执行的exe文件,让其在后台执行即可.

php爬虫采集数据并发执行问题-图1

其他.比如,使用网速好的网络等等.

如何用php 编写网络爬虫

提供给你我之前写的类:curl.php ?希望可以帮到你.

QueryList.php和phpQuery.php由于文件太大了,没办法贴上来

php

php爬虫采集数据并发执行问题-图2

class?Http?{

public?function?curlRequest($url,?$postData?=?'',?$timeOut?=?10,?$httpHeader?=?array())?{

$handle?=?curl_init?();

curl_setopt?(?$handle,?CURLOPT_URL,?$url?);

if?($httpHeader)?{

curl_setopt($handle,?CURLOPT_HTTPHEADER,?$httpHeader);

}

curl_setopt?(?$handle,?CURLOPT_RETURNTRANSFER,?true?);

curl_setopt?(?$handle,?CURLOPT_HEADER,?0?);???????????curl_setopt?(?$handle,?CURLOPT_TIMEOUT,?$timeOut?);

curl_setopt?(?$handle,?CURLOPT_FOLLOWLOCATION,?1?);

curl_setopt?(?$handle,?CURLOPT_SSL_VERIFYPEER,?false?);

curl_setopt?(?$handle,?CURLOPT_SSL_VERIFYHOST,?false?);

if?(!?empty?(?$postData?))?{

curl_setopt?(?$handle,?CURLOPT_POST,?1?);

curl_setopt?(?$handle,?CURLOPT_POSTFIELDS,?$postData);

php爬虫采集数据并发执行问题-图3

$result['response']?=?curl_exec?(?$handle?);

$result['httpStatus']?=?curl_getinfo?(?$handle,?CURLINFO_HTTP_CODE?);

$result['fullInfo']?=?curl_getinfo?(?$handle?);

$result['errorMsg']?=?'';

$result['errorNo']?=?0;

if?(curl_errno($handle))?{

$result['errorMsg']?=?curl_error($handle);

$result['errorNo']?=?curl_errno($handle);

curl_close?(?$handle?);

return?$result;

php中产生的并发问题一般如何解决?

您好,并发问题一般使用nosql进行解决,例如Redis等进行削峰处理

如何处理数据库并发问题

想要知道如何处理数据并发,自然需要先了解数据并发.

什么是数据并发操作呢?

就是同一时间内,不同的线程同时对一条数据进行读写操作.

在互联网时代,一个系统常常有很多人在使用,所以呢就可能出现高并发的现象,也就是不同的用户同时对一条数据进行操作,如果没有有效的处理,自然就会出现数据的异常.而最常见的一种数据并发的场景就是电商中的秒杀,成千上万个用户对在极端的时间内,抢购一个商品.针对这种场景,商品的库存就是一个需要控制的数据,而多个用户对在同一时间对库存进行重写,一个不小心就可能出现超卖的情况.

针对这种情况,我们如何有效的处理数据并发呢?

第一种方案、数据库锁

从锁的基本属性来说,可以分为两种:一种是共享锁(S),一种是排它锁(X).在MySQL的数据库中,是有四种隔离级别的,会在读写的时候,自动的使用这两种锁,防止数据出现混乱.

这四种隔离级别分别是:

读未提交(Read Uncommitted)

读提交(Read Committed)

可重复读(Repeated Read)

串行化(Serializable)

当然,不同的隔离级别,效率也是不同的,对于数据的一致性保证也就有不同的结果.而这些可能出现的又有哪些呢?

脏读(dirty read)

当事务与事务之间没有任何隔离的时候,就可能会出现脏读.例如:商家想看看所有的订单有哪些,这时,用户A提交了一个订单,但事务还没提交,商家却看到了这个订单.而这时就会出现一种问题,当商家去操作这个订单时,可能用户A的订单由于部分问题,导致数据回滚,事务没有提交,这时商家的操作就会失去目标.

不可重复读(unrepeatable read)

一个事务中,两次读操作出来的同一条数据值不同,就是不可重复读.

例如:我们有一个事务A,需要去查询一下商品库存,然后做扣减,这时,事务B操作了这个商品,扣减了一部分库存,当事务A再次去查询商品库存的时候,发现这一次的结果和上次不同了,这就是不可重复读.

幻读(phantom problem)

一个事务中,两次读操作出来的结果集不同,就是幻读.

例如:一个事务A,去查询现在已经支付的订单有哪些,得到了一个结果集.这时,事务B新提交了一个订单,当事务A再次去查询时,就会出现,两次得到的结果集不同的情况,也就是幻读了.

那针对这些结果,不同的隔离级别可以干什么呢?

"读未提(Read Uncommitted)"能预防啥?啥都预防不了.

"读提交(Read Committed)"能预防啥?使用"快照读(Snapshot Read)"方式,避免"脏读",但是可能出现"不可重复读"和"幻读".

"可重复读(Repeated Red)"能预防啥?使用"快照读(Snapshot Read)"方式,锁住被读取记录,避免出现"脏读"、"不可重复读",但是可能出现"幻读".

"串行化(Serializable)"能预防啥?有效避免"脏读"、"不可重复读"、"幻读",不过运行效率奇差.

好了,锁说完了,但是,我们的数据库锁,并不能有效的解决并发的问题,只是尽可能保证数据的一致性,当并发量特别大时,数据库还是容易扛不住.那解决数据并发的另一个手段就是,尽可能的提高处理的速度.

因为数据的IO要提升难度比较大,那么通过其他的方式,对数据进行处理,减少数据库的IO,就是提高并发能力的有效手段了.

最有效的一种方式就是:缓存

想要减少并发出现的概率,那么读写的效率越高,读写的执行时间越短,自然数据并发的可能性就变小了,并发性能也有提高了.

还是用刚才的秒杀举例,我们为的就是保证库存的数据不出错,卖出一个商品,减一个库存,那么,我们就可以将库存放在内存中进行处理.这样,就能够保证库存有序的及时扣减,并且不出现问题.这样,我们的数据库的写操作也变少了,执行效率也就大大提高了.

当然,常用的分布式缓存方式有:Redis和Memcache,Redis可以持久化到硬盘,而Memcache不行,应该怎么选择,就看具体的使用场景了.

当然,缓存毕竟使用的范围有限,很多的数据我们还是必须持久化到硬盘中,那我们就需要提高数据库的IO能力,这样避免一个线程执行时间太长,造成线程的阻塞.

那么,读写分离就是另一种有效的方式了

当我们的写成为了瓶颈的时候,读写分离就是一种可以选择的方式了.

我们的读库就只需要执行读,写库就只需要执行写,把读的压力从主库中分离出去,让主库的资源只是用来保证写的效率,从而提高写操作的性能.

php curl 大量数据采集

这个需要配合js,打开一个html页面,首先js用ajax请求页面,返回第一个页面信息确定处理完毕(ajax有强制同步功能),ajax再访问第二个页面.(或者根据服务器状况,你可以同时提交几个URL,跑几个相同的页面)

参数可以由js产生并传递url,php后台页面根据URL抓页面.然后ajax通过php,在数据库或者是哪里设一个标量,标明检测到哪里.由于前台的html页面执行多少时候都没问题,这样php的内存限制和执行时间限制就解决了.

如何将单机爬虫的并发请求提高到50+qps

思路

这次的的爬虫是上次那个的升级版,不过呢,上次那个虽然是简单,但是很适合新手学习啊.这次的爬虫代码在我的github上可以找到=NodeSpider.

抓取页面初始的数据很简单啊,这里就不做多解释啦

/*获取首屏所有图片链接*/ var getInitUrlList=function(){ request.get("") .end(function(err,res){ if(err){ console.log(err); }else{ var $=cheerio.load(res.text); var answerList=$(".zm-item-answer"); answerList.map(function(i,answer){ var images=$(answer).find('.zm-item-rich-text img'); images.map(function(i,image){ photos.push($(image).attr("src")); }); }); console.log("已成功抓取"+photos.length+"张图片的链接"); getIAjaxUrlList(); } }); }

模拟ajax请求获取完整页面

有了这些信息,就可以来模拟发送相同的请求来获得这些数据啦.

/*每隔毫秒模拟发送ajax请求,并获取请求结果中所有的图片链接*/ var getIAjaxUrlList=function(offset){ request.post("") .set(config) .send("method=next?ms=%B%url_token%%A%C%pagesize%%A%C%offset%%A" +offset+ "%D_xsrf=adfdeee") .end(function(err,res){ if(err){ console.log(err); }else{ var response=JSON.parse(res.text);/*想用json的话对json序列化即可,提交json的话需要对json进行反序列化*/ if(response.msgresponse.msg.length){ var $=cheerio.load(response.msg.join(""));/*把所有的数组元素拼接在一起,以空白符分隔,不要这样join(),它会默认数组元素以逗号分隔*/ var answerList=$(".zm-item-answer"); answerList.map(function(i,answer){ var images=$(answer).find('.zm-item-rich-text img'); images.map(function(i,image){ photos.push($(image).attr("src")); }); }); setTimeout(function(){ offset+=; console.log("已成功抓取"+photos.length+"张图片的链接"); getIAjaxUrlList(offset); },); }else{ console.log("图片链接全部获取完毕,一共有"+photos.length+"条图片链接"); // console.log(photos); return downloadImg(); } } }); }

今天这一节用到了一个神奇的模块=async,它不仅能帮我们拜托难以维护的回调金字塔恶魔,还能轻松的帮我们进行异步流程的管理.具体看文档啦,因为我自己也不怎么会用,这里就只用到了一个强大的async.mapLimit方法.真的很厉害哦.

以上所述给大家介绍了Nodejs爬虫进阶教程之异步并发控制的相关知识,希望大家如果觉得本站发布的文章不错,请转发分享给您身边的朋友,您的支持是我们最大的动力.

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章