设为首页收藏本站

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 119|回复: 0

PHP批量采集下载图片

[复制链接]
发表于 2014-1-3 15:29:23 | 显示全部楼层 |阅读模式
最近在浏览某个美女网站,但是考虑到网速问题,这种网站打开速度慢,广告多,随机想到使用php采集一下这些美女图片

设计思路

考虑到单纯的采集一个网页的图片,太麻烦,所以直接采集他的列表页,获取列表的url然后在一一采集,但是用php匹配列表页的url太麻烦,第一列表页有很多无效url这对我这个正则小菜鸟实在是个问题,看了一下列表页的结构,果断采用 jquery获取url,jquery的万能选择器又再次强大起来了。

jquery获取url,然后ajax传递url—>对应PHP文件,遍历url参数—->单页面采集保存图片

jquery程序
  1. <script src="http://www.cztv.com/uibase/jquery.js"></script>
  2. <script >
  3. $(document).ready(function(){
  4. var hrefs ='';
  5. $('.f_folder>a').each(function(i){
  6. var href = $('.f_folder:eq('+i+')>a:eq(0)').attr('href');
  7. if(href!='undefined'){
  8. hrefs +=href+',';
  9. }
  10. })
  11. $.getJSON("http://www.****.com/365/getimg.php?hrefs="+hrefs+"&callback=?", function(data){
  12. //alert(data.info);
  13. });
  14. });
  15. </script>
复制代码

这里把url拼接成‘,'分割的字符串传递url,使用getjson是为了跨域需要,关于getjson常见的几个问题可以参看<$.getjson遇到的几个问题>

PHP采集程序
  1. <?php
  2. // 抓起365图片
  3. error_reporting(E_ALL ^ E_NOTICE);
  4. set_time_limit(0);//设置PHP超时时间
  5. /**
  6. * 得到当前时间
  7. */
  8. function getMicrotime() {

  9. list ($usec, $sec) = explode(" ", microtime());
  10. return ((float) $usec + (float) $sec);
  11. }
  12. $stime = getMicrotime();

  13. $callback = $_GET['callback'];
  14. $hrefs = $_GET['hrefs'];
  15. $urlarray = explode(',',$hrefs);

  16. //获取指定url的所有图片
  17. function getimgs($url){
  18. $dirname = basename($url,".php");
  19. if(!file_exists($dirname)){
  20. mkdir('365/'.$dirname.'');
  21. }
  22. clearstatcache();
  23. $data = file_get_contents($url);
  24. preg_match_all("/(href|src)=(["|']?)([^ "'>]+.(jpg|png|PNG|JPG|gif))\2/i", $data, $matches);
  25. //$matches[3] = array_unique($matches[3]);
  26. unset($data);
  27. $i=0;

  28. if(count($matches[3])>0){
  29. foreach($matches[3] as $k=>$v){
  30. //简单判断是否是标准url,而不是相对路径
  31. if(substr($v,0,4)=='http'){

  32. $ext = pathinfo($v,PATHINFO_EXTENSION);//图片扩展

  33. if(!file_exists('365/'.$dirname.'/'.$k.'.'.$ext)){
  34. file_put_contents('365/'.$dirname.'/'.$k.'.'.$ext,file_get_contents($v));
  35. $i++;
  36. }else{
  37. unset($v);
  38. }
  39. clearstatcache();
  40. }else{
  41. unset($v);
  42. }
  43. }
  44. unset($matches);
  45. return $i;
  46. }
  47. }

  48. foreach($urlarray as $k=>$v){
  49. if($v!=''){
  50. $j +=getimgs($v);
  51. }
  52. }
  53. $etime = getMicrotime();
  54. echo "合计采集了".$j."张图片";
  55. echo "用时".($etime-$stime)."秒";
复制代码

考虑到性能问题:在getimgs方法中所用的变量都是使用后便注销(unset)了,以便释放内存。

设计到的几个知识点

判断是否是标准有效图片url
if(substr($v,0,4)=='http') 这个只是简单的判断一下匹配到的图片url是否是标准的url,因为采集的图片可能是相对路径的,这里我直接放弃这种图片的采集,当然你也可以把这种图片还原成标准图片路径,还有一个问题就是即使是标准url格式,这样的图片也未必可以采集,因为你不知道这个图片是否还有,也许这个图片url已经无效了,如果你想更严格的判断这个图片url是否真实有效可以推荐看我之前的《PHP判断远程url是否有效的几种方法》有三种方法可以验证是否是有效url。

获取图片格式

$ext = pathinfo($v,PATHINFO_EXTENSION);//图片扩展

这里使用了pathinfo的方法,总结有7种方法可以获取到文件的格式,推荐文章:《PHP判断图片格式的七种方法

下载保存到本地

file_put_contents('365/'.$dirname.'/'.$k.'.'.$ext,file_get_contents($v));
file_put_contents() 函数把一个字符串写入文件中。
与依次调用 fopen(),fwrite() 以及 fclose() 功能一样。
file_get_contents() 函数把整个文件读入一个字符串中。

因为服务器支持file_get_contents,如果服务器把这个函数禁用了,可以使用curl,这个工具要比file_get_contents更加强大,推荐学习《CURL的学习和应用(附多线程)》,可以使用curl的多线程下载存储,效果更牛逼

清除文件操作缓存

clearstatcache() 函数清除文件状态缓存。clearstatcache() 函数会缓存某些函数的返回信息,以便提供更高的性能。但是有时候,比如在一个脚本中多次检查同一个文件,而该文件在此脚本执行期间有被删除或修改的危险时,你需要清除文件状态缓存,以便获得正确的结果。要做到这一点,就需要使用 clearstatcache() 函数。官方手册:

程序执行时间计算
  1. /**

  2. * 得到当前时间

  3. */

  4. function getMicrotime() {
  5. list ($usec, $sec) = explode(" ", microtime());
  6. return ((float) $usec + (float) $sec);
  7. }
复制代码

最后看一下效果;



409秒采集了214张图片,大概2秒下载保存了一张图片,图片总大小约62M,这样看来:

一个小时60*60可以大约下载1800张美女图片。 来自圈子: Demo俱乐部
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|小黑屋|BC Morning Website ( Best Deal Inc. 001 )  

GMT-8, 2025-12-12 22:33 , Processed in 0.012859 second(s), 20 queries .

Supported by Best Deal Online X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表