当前位置: 首页 > news >正文

PHP利用Curl实现多线程抓取网页和下载文件

PHP 利用 Curl  可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,然而因为php语言本身不支持多线程,所以开发爬虫程序效率并不高,一般采集 数据可以利用 PHPquery类来采集数据库,在此之外也可以用 Curl ,借助Curl 这个功能实现并发多线程的访问多个url地址以实现并发多线程抓取网页或者下载文件.

至于具体实现过程,请参考下面几个例子:

1、实现抓取多个URL并将内容写入指定的文件

  1. $urls = array( 
  2. '路径地址', 
  3. '路径地址', 
  4. '路径地址' 
  5. ); // 设置要抓取的页面URL 
  6. $save_to='/test.txt'; // 把抓取的代码写入该文件 
  7. $st = fopen($save_to,"a"); 
  8. $mh = curl_multi_init(); 
  9. foreach ($urls as $i => $url) { 
  10. $conn[$i] = curl_init($url); 
  11. curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
  12. curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
  13. curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
  14. curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件 
  15. curl_multi_add_handle ($mh,$conn[$i]); 
  16. } // 初始化 
  17. do { 
  18. curl_multi_exec($mh,$active); 
  19. } while ($active); // 执行 
  20. foreach ($urls as $i => $url) { 
  21. curl_multi_remove_handle($mh,$conn[$i]); 
  22. curl_close($conn[$i]); 
  23. } // 结束清理 
  24. curl_multi_close($mh); 
  25. fclose($st);
复制

2、利用 PHP 的 Curl  实现抓取网页URL并保存内容

下面这段代码和上面差不多意思,只不过这个地方是将获得的代码先放入变量,然后再将获取到的内容写入指定的文件

  1. $urls = array( 
  2. '路径地址', 
  3. '路径地址', 
  4. '路径地址' 
  5. ); 
  6. $save_to='/test.txt'; // 把抓取的代码写入该文件 
  7. $st = fopen($save_to,"a"); 
  8. $mh = curl_multi_init(); 
  9. foreach ($urls as $i => $url) { 
  10. $conn[$i] = curl_init($url); 
  11. curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
  12. curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
  13. curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
  14. curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串 
  15. curl_multi_add_handle ($mh,$conn[$i]); 
  16. } 
  17. do { 
  18. curl_multi_exec($mh,$active); 
  19. } while ($active); 
  20. foreach ($urls as $i => $url) { 
  21. $data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串 
  22. fwrite($st,$data); // 将字符串写入文件
  23. } // 获得数据变量,并写入文件 
  24. foreach ($urls as $i => $url) { 
  25. curl_multi_remove_handle($mh,$conn[$i]); 
  26. curl_close($conn[$i]); 
  27. }
  28. curl_multi_close($mh); 
  29. fclose($st);
复制

3、利用 PHP 的 Curl  实现并发多线程下载文件

  1. $urls=array(
  2. '路径地址5w.zip',
  3. '路径地址5w.zip',
  4. '路径地址5w.zip'
  5. );
  6. $save_to='./home/';
  7. $mh=curl_multi_init();
  8. foreach($urls as $i=>$url){
  9. $g=$save_to.basename($url);
  10. if(!is_file($g)){
  11. $conn[$i]=curl_init($url);
  12. $fp[$i]=fopen($g,"w");
  13. curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
  14. curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
  15. curl_setopt($conn[$i],CURLOPT_HEADER ,0);
  16. curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
  17. curl_multi_add_handle($mh,$conn[$i]);
  18. }
  19. }
  20. do{
  21. $n=curl_multi_exec($mh,$active);
  22. }while($active);
  23. foreach($urls as $i=>$url){
  24. curl_multi_remove_handle($mh,$conn[$i]);
  25. curl_close($conn[$i]);
  26. fclose($fp[$i]);
  27. }
  28. curl_multi_close($mh);$urls=array(
  29. '路径地址5w.zip',
  30. '路径地址5w.zip',
  31. '路径地址5w.zip'
  32. );
  33. $save_to='./home/';
  34. $mh=curl_multi_init();
  35. foreach($urls as $i=>$url){
  36. $g=$save_to.basename($url);
  37. if(!is_file($g)){
  38. $conn[$i]=curl_init($url);
  39. $fp[$i]=fopen($g,"w");
  40. curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
  41. curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
  42. curl_setopt($conn[$i],CURLOPT_HEADER ,0);
  43. curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
  44. curl_multi_add_handle($mh,$conn[$i]);
  45. }
  46. }
  47. do{
  48. $n=curl_multi_exec($mh,$active);
  49. }while($active);
  50. foreach($urls as $i=>$url){
  51. curl_multi_remove_handle($mh,$conn[$i]);
  52. curl_close($conn[$i]);
  53. fclose($fp[$i]);
  54. }
  55. curl_multi_close($mh);
复制

 

相关文章:

  • Java Logback教程
  • 石子合并[DP-N3]
  • log4j2定期生成和删除过期日志文件的配置
  • 使用netcat进行反弹链接的shellcode
  • mybatis 判断是否传入了某参数
  • sleep()和wait()区别
  • [LeetCode] NO. 387 First Unique Character in a String
  • Linux命令(网络)
  • 抽象工厂的一个范例
  • WebBrowser 和 Win Form 的关闭问题?
  • 蓝鸥Unity开发基础二——课时18 单例
  • 表示数值的字符串
  • 如何配置搜索功能
  • W3bsafe]SQLmap过狗命令的利用+教程
  • Linux的包管理工具介绍
  • Golang-长连接-状态推送
  • Laravel Mix运行时关于es2015报错解决方案
  • Lsb图片隐写
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • ReactNativeweexDeviceOne对比
  • supervisor 永不挂掉的进程 安装以及使用
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 前端面试之CSS3新特性
  • 事件委托的小应用
  • 新版博客前端前瞻
  • 一天一个设计模式之JS实现——适配器模式
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • postgresql行列转换函数
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #图像处理
  • (007)XHTML文档之标题——h1~h6
  • (AngularJS)Angular 控制器之间通信初探
  • (LeetCode C++)盛最多水的容器
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (利用IDEA+Maven)定制属于自己的jar包
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (算法)求1到1亿间的质数或素数
  • (循环依赖问题)学习spring的第九天
  • ***原理与防范
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .gitignore文件---让git自动忽略指定文件
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .NET微信公众号开发-2.0创建自定义菜单
  • .NET中的Exception处理(C#)
  • /3GB和/USERVA开关