使用PHP抓取Bing每日图像并为己所用

mengkun 27.2K 50

Bing搜索的首页每天都会推送一张很漂亮的图片,把它保存下来,当做电脑桌面或是自己的网站背景图还不是美滋滋…… [微笑]

今天的bing图片是这样的

既然要抓取这张图片,首先就得弄清这张图是从何而来的。经过对必应首页的抓包,我们可以获得首页图的获取API。它的格式是这样的:

  1. http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1

注意,这里有几个GET参数,它们的作用分别是:

  • n,必要参数。这是输出信息的数量。比如n=1,即为1条,以此类推,至多输出8条。
  • format,非必要。返回结果的格式,不存在或者等于xml时,输出为xml格式,等于js时,输出json格式
  • idx,非必要。不存在或者等于0时,输出当天的图片,-1为已经预备用于明天显示的信息,1则为昨天的图片,以此类推,idx最多获取到前16天的图片信息

这里将n设定为1、format设定为js、idx设定为1,去发出GET请求,返回的数据是这样的:

  1. {
  2.     "images": [
  3.         {
  4.             "startdate": "20161222",
  5.             "fullstartdate": "201612221600",
  6.             "enddate": "20161223",
  7.             "url": "/az/hprichbg/rb/TheDomeEdinburgh_ZH-CN11993142817_1920x1080.jpg",
  8.             "urlbase": "/az/hprichbg/rb/TheDomeEdinburgh_ZH-CN11993142817",
  9.             "copyright": "爱丁堡一家叫做The Dome的夜店,苏格兰 (© Marty McKillop/500px)",
  10.             "copyrightlink": "http://www.bing.com/search?q=The+Dome,+Edinburgh&form=hpcapt&mkt=zh-cn",
  11.             "quiz": "/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20161222_TheDomeEdinburgh%22&FORM=HPQUIZ",
  12.             "wp": false,
  13.             "hsh": "376393c9b49c6d8d1a6e7c2d38343105",
  14.             "drk": 1,
  15.             "top": 1,
  16.             "bot": 1,
  17.             "hs": []
  18.         }
  19.     ],
  20.     "tooltips": {
  21.         "loading": "正在加载...",
  22.         "previous": "上一个图像",
  23.         "next": "下一个图像",
  24.         "walle": "此图片不能下载用作壁纸。",
  25.         "walls": "下载今日美图。仅限用作桌面壁纸。"
  26.     }
  27. }

其中的“images”节点下的“url”值便是我们要获取的图像地址。我们把它取出来,再加上Bing的网址前缀(http://cn.bing.com)即组合成了完整的图像地址。比如说上面返回数据的完整图像地址是这样的:

  1. http://cn.bing.com/az/hprichbg/rb/TheDomeEdinburgh_ZH-CN11993142817_1920x1080.jpg

知道了背景图的获取方式,接下来就是用PHP去动态抓取了。

如果你只是单纯的想用作网页背景的话,你只需新建一个php文件,里面贴入如下代码:

<?php
$str = file_get_contents('http://cn.bing.com/HPImageArchive.aspx?idx=0&n=1');   // 从bing获取数据

if(preg_match('/<url>([^<]+)<\/url>/isU', $str, $matches)) { // 正则匹配抓取图片url
    $imgurl = 'http://cn.bing.com'.$matches[1];
} else {  // 如果由于某些原因,没抓取到图片地址
    $imgurl = 'http://img.infinitynewtab.com/InfinityWallpaper/2_14.jpg'; // 使用默认的图像(默认图像链接可修改为自己的)
}

header("Location: {$imgurl}");    // 跳转至目标图像

然后把这个php文件上传到你的服务器或者是网站空间,访问这个php应该就能看到被跳转到了Bing的图片。

使用方法:直接将那个php文件的绝对地址当做图片放进网页中即可。

比如说,如果你的这个php的地址为“http://www.myweb.cn/bing.php”,那么你在你自己的网页的css中这么写就能当背景使用了:

  1. body{
  2.     width:100%;
  3.     height:100%;
  4.     backgroundurl(http://www.myweb.cn/bing.php) no-repeat;
  5.     -moz-background-size: cover;    /*背景图片拉伸以铺满全屏*/
  6.     -ms-background-size: cover;
  7.     -webkit-background-size: cover;
  8.     background-size: cover;
  9. }

以上方法只是简单地跳转,如果想要抓取这张图片并保存到服务器呢?这里直接贴代码:

  1. <?php
  2. /**
  3.  * php抓取bing每日图片并保存到服务器
  4.  * 作者:mengkun (mkblog.cn)
  5.  * 日期:2016/12/23
  6.  */
  7. $path = 'temp';   //设置图片缓存文件夹
  8. $filename = date("Ymd") . '.jpg';  //用年月日来命名新的文件名
  9. if (!file_exists($path.'/'. $filename))    //如果文件不存在,则说明今天还没有进行缓存
  10. {
  11.     if(!file_exists($path)) //如果目录不存在
  12.     {
  13.         mkdir($path, 0777); //创建缓存目录
  14.     }
  15.     $str = file_get_contents('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1'); //读取必应api,获得相应数据
  16.     $str = json_decode($str,true);
  17.     $imgurl = 'http://cn.bing.com'.$str['images'][0]['url'];    //获取图片url
  18.     $img = grabImage($imgurl$path.'/'.$filename); //读取并保存图片
  19.     $handle = fopen("dat.txt""a");    //用于存放图片信息,如果不需要保存图片的相关信息,可以把下面这些去掉。
  20.     if ($handle)
  21.     {
  22.         $copyright = $str['images'][0]['copyright'];    //说明
  23.         $startdate = $str['images'][0]['startdate'];
  24.         $fullstartdate = $str['images'][0]['fullstartdate'];
  25.         $enddate = $str['images'][0]['enddate'];
  26.         $urlbase = $str['images'][0]['urlbase'];
  27.         $copyrightlink = $str['images'][0]['copyrightlink'];
  28.         $quiz = $str['images'][0]['quiz'];
  29.         $wp = $str['images'][0]['wp'];
  30.         $hsh = $str['images'][0]['hsh'];
  31.         $drk = $str['images'][0]['drk'];
  32.         $top = $str['images'][0]['top'];
  33.         $bot = $str['images'][0]['bot'];
  34.         $tempArr = array("imgurl"=>$imgurl,"copyright"=>$copyright"startdate"=>$startdate,
  35.         "fullstartdate"=>$fullstartdate"enddate"=> $enddate"urlbase"=>$urlbase,
  36.         "copyrightlink"=> $copyrightlink"quiz"=>$quiz"wp"=> $wp,
  37.         "hsh"=>$hsh,"drk"=>$drk"top"=> $top"bot"=> $bot);   //将相关信息放进数组中
  38.         fwrite($handle, json_encode($tempArr) ."\r\n"); //最终以json格式保存在文本文档中
  39.         fclose($handle);
  40.     }
  41. }
  42. /**
  43.  * 远程抓取图片并保存
  44.  * @param $url 图片url
  45.  * @param $filename 保存名称和路径
  46.  */
  47. function grabImage($url$filename = "")
  48. {
  49.     if($url == ""return false; //如果$url地址为空,直接退出
  50.     if ($filename == ""//如果没有指定新的文件名
  51.     {
  52.         $ext = strrchr($url".");  //得到$url的图片格式
  53.         $filename = date("Ymd") . $ext;  //用天月面时分秒来命名新的文件名
  54.     }
  55.     ob_start();         //打开输出
  56.     readfile($url);     //输出图片文件
  57.     $img = ob_get_contents();   //得到浏览器输出
  58.     ob_end_clean();             //清除输出并关闭
  59.     $size = strlen($img);       //得到图片大小
  60.     $fp2 = @fopen($filename"a");
  61.     fwrite($fp2$img);         //向当前目录写入图片文件,并重新命名
  62.     fclose($fp2);
  63.     return $filename;           //返回新的文件名
  64. }

这样,如果这个php被访问,它就会自动启动抓取并保存。你可以用阿里云监控或其他类型的网站监控服务来实现每天自动运行这个php。

我这里挂在服务器上测试了一下,已经成功运行了三天:
使用PHP抓取Bing每日图像并为己所用

发表评论 取消回复
表情 图片 链接 代码

  1. 懒猫爱伸腰
    懒猫爱伸腰 Lv 1

    是不可以挂个网站监控,设置成周期24小时,就可以全自动了[aru_1]

  2. 聚点滴
    聚点滴 Lv 1

    自己弄得那个接口也可以把idx参数放上

  3. 聚点滴
    聚点滴 Lv 1

    参数idx好像只能到6,不是16啊

  4. BObby
    BObby Lv 1

    图片的信息如何提取?

  5. 月明天涯
    月明天涯 Lv 1

    #17楼的代码补充。
    【如果你使用的服务器或者空间,时区不为中国标准时区,那么你可以在源码开头处添加以下代码。来实现时区同步。使目录和文件的命名与中国时区一致。】

    ini_set('date.timezone','Asia/Shanghai');  //设置时区,确定为中国上海时区
    • 月明天涯
      月明天涯 Lv 1

      @月明天涯如果时区差距较大时,可以折腾一下。时区相差几个小时的话。。。。

  6. 月明天涯
    月明天涯 Lv 1

    大佬也喜欢收藏必应美图么?[aru_12]我从2016年中旬,一直抓取必应美图。途中,机房维护、域名备案,中断了几次,挺可惜的。
    不过大佬。我寻思你这个采集后,目录会有点乱。。[aru_2]
    借大佬博客,分享一下我的采集源码,需要的就拿去用吧。采集的文件,目录会比较整齐。
    同时,欢迎大家常来我的博客玩耍儿^~^

    <?php
    /**
     * 名称:必应每日图片自动抓取
     * 作者:月明天涯
     * 日期:2016/04/16
     * 博客:http://blog.heheda.top
     * QQ:2585649532
     */
    $path='IMG';   //定义存放图片的一级目录,这个目录是固定的,需要手动创建并设置写入权
    $path1=$path.'/'.date('Y');  //定义存放图片的二级目录,以当前所处年份来命名
    if(!file_exists($path1)){mkdir($path1,0777);}  //判断二级目录是否存在,若不存在,则自动创建并设置写入权
    $path2=$path1.'/'.date('m');  //定义存放图片的三级目录,以当前所处月份来命名
    if(!file_exists($path2)){mkdir($path2,0777);}   //判断三级目录是否存在,若不存在,则自动创建并设置写入权
    $pathurl=$path2.'/'.date('d').'.jpg';   //定义图片名,以当前所处日份来命名
    if(!is_file($pathurl)){
    $str=file_get_contents('http://cn.bing.com/HPImageArchive.aspx?idx=0&n=1');   //获取图片地址,并判断图片是否已经存在
     if(preg_match("/<urlBase>(.+?)<\/urlBase>/ies",$str,$matches)){
      $imgurl='http://cn.bing.com'.$matches[1].'_1920x1080.jpg';
      copy($imgurl,$pathurl);}  //读取对应的图片并写入指定目录
      }
    header('Content-Type:image/jpeg');  //定义输出类型
    @ob_end_clean();   //擦除缓存
    @readfile($pathurl);  //输出本地图片
    @flush();   //缓存
    @ob_flush();   //输出缓存 
    exit();  //退出
    ?>
  7. 轩沫博客
    轩沫博客 Lv 4

    学编程开头容易坚持难啊。

  8. 执子之手
    执子之手 Lv 1

    https://www.yuluoge.com/api/index.php 大佬,我想搞成这个接口,可是整了很久搞不定啊。据说这个接口里面有三万多张图片。望大佬指点一下。

    • 九凌少子
      九凌少子 Lv 1

      @执子之手 查看图片
      图片都是360壁纸提供的,php请求360壁纸api后把获取到的json里面的图片链接全部保存到txt文件就可以

    • 九凌少子
      九凌少子 Lv 1

      @执子之手借孟坤大佬地盘打个广告,我写了一个接口教程https://www.yuluoge.com/course/284.html

  9. Python使用Flask抓取Bing每日图像 | 木一博客
    Python使用Flask抓取Bing每日图像 | 木一博客 Pingback

    […] 相关推荐: [1].使用PHP抓取Bing每日图像并为己所用.孟坤博客.https://mkblog.cn/492/ […]

  10. erik
    erik Lv 1

    请问怎么抓取190x1080的图呢

  11. ireli
    ireli Lv 1

    找到了 刷新一下就有了

  12. ireli
    ireli Lv 1

    查看图片 emmm怎么回事....

  13. 菜鸡
    菜鸡 Lv 1

    如何抓到这个api呀http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1,我用开发者工具打开的是这个玩意https://cn.bing.com/az/hprichbg/rb/Peloton_ZH-CN7472605035_1920x1080.jpg

    • mengkun
      mengkun 站长
      • 菜鸡
        菜鸡 Lv 1

        @mengkun咦,怎么可以一眼看出来这个就是背景图片的api呢

      • mengkun
        mengkun 站长

        @菜鸡没啥特殊的技巧,只能一个个点开看

      • 菜鸡
        菜鸡 Lv 1

        @mengkun哈哈哈好,多谢大佬解答

  14. mandolin
    mandolin Lv 1

    感谢楼主大神 就是bing图片对应的文字介绍 还是无法显示出来 “最终以json格式保存在文本文档中”没找到这个dat.txt啊...

  15. 学习学习
    学习学习 Lv 1

    谢谢站长 学习了

  16. 产品汇
    产品汇 Lv 1

    必应壁纸的描述(故事)是怎么获取的?

    • mengkun
      mengkun 站长

      @产品汇上面的最后一段代码里都有

  17. 你好
    你好 Lv 1

    [aru_44]666,很不错

  18. 阿龙啊
    阿龙啊 Lv 1

    怎么调用1920×1080的?你1评论里的哪个放进去显示错误不能用

    • mengkun
      mengkun 站长

      @阿龙啊要把内容中的中文引号改为英文的引号(PHP 基本常识。。。)

  19. 紫薇恋人
    紫薇恋人 Lv 1

    这个PHP每次只能保存一张,我想保存每天主页的全部图片,怎么玩?包含360的。图片远程本地化,直接全部保存到自己服务器。。或是通过接口直接传到七牛啊 景安对象存储什么的存储空间.

    • 365cent
      365cent Lv 3

      @紫薇恋人必应每天只有一张哦,左右翻的是之前的

  20. okfree
    okfree Lv 1

    博主 如果我想每次刷新都变不同图片 如何做呢
    最好没有8张图片的限制 谢谢

    • mengkun
      mengkun 站长

      @okfree给个思路:
      将 bing 的图片缓存在服务器(上面已提供有代码),然后再从自己的服务器随机读取图片(这部分需自己写,可以参照 http://www.jb51.net/article/69392.htm)。

  21. 林子鱼
    林子鱼 Lv 1

    坤哥,我问下,你上面的那个直接当作背景的简单写法,为啥读出来的图只有1366x768,怎么让他读出1920x1080呢?? [呲牙]

    • mengkun
      mengkun 站长

      @林子鱼用这一段:

      <?php
      $str = file_get_contents('http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1'); //读取必应api,获得相应数据
      $str = json_decode($str,true);
      $imgurl = 'http://cn.bing.com'.$str['images'][0]['url'];    //获取图片url
      header("Location: $imgurl");    //header跳转
      
      • nmcapt
        nmcapt Lv 1

        @mengkun这个怎么用 不行啊 报错[aru_6]

  22. 266277
    266277 Lv 4

    空间也是可以的吧 那多谢咯

    • mengkun
      mengkun 站长

      @266277只要是支持 php 的网站空间(或服务器),并且目录具有写入权限就可以使用。

      • 266277
        266277 Lv 4

        @mengkun昨天那个php可以访问今天怎么不行了 [疑问]

      • mengkun
        mengkun 站长

        @266277哪个php?

      • 266277
        266277 Lv 4

        @mengkun保存图片的php 现在访问不了 http://www.xiaohong.pw/bing

      • mengkun
        mengkun 站长

        @266277我 Ping 了一下你的网站,发现全部都无响应。可能是因为网站空间出问题了。建议你登录网站空间的控制面板检查一下。

      • 266277
        266277 Lv 4

        @mengkun好了 空间的问题 最后还想问下博主你必应美图只能翻16张就不可以了吗

      • mengkun
        mengkun 站长

        @266277必应官方的设定就是只支持 16 张……所以才要把图片给保存到服务器嘛,这样才能随时使用。

  23. 266277
    266277 Lv 4

    这个PHP怎么实现保存到本地的服务器

    • mengkun
      mengkun 站长

      @266277没用过本地服务器,不知道本地服务器与远程服务器有什么区别,无法回答 [衰]

      • 266277
        266277 Lv 4

        @mengkun不是 我就是说win的服务器这个php怎么自动的保存的

      • mengkun
        mengkun 站长

        @266277先在服务器上新建一个 php 文档,然后把那段代码复制粘贴进去,保存。然后可以用阿里云监控之类的服务实现每天自动访问这个 php 。方法可以参照 http://mkblog.cn/233/

  24. 使用PHP抓取Bing每日图像并为己所用 | 上下博客
    使用PHP抓取Bing每日图像并为己所用 | 上下博客 Pingback

    […] 孟坤博客 , 于刚刚,由 updown 整理发表,共 […]

  25. 分享一枚获取高清壁纸的api | 孟坤博客
    分享一枚获取高清壁纸的api | 孟坤博客 Pingback

    […] 我把这些接口以及前段时间的必应每日图片接口整合在了一起,花了几天时间做了个壁纸下载站: […]

分享