问题

之前写的将豆瓣我看过的电影整合到wordpress豆瓣
经过测试,当豆瓣数据太多时,因为是采集“我看过的电影”,循环采集时间太长
报错信息:504 Gateway Time-out

测试数据

500条豆瓣电影。

解决

方法1

如可以修改php配置文件,可修改配置文件,解决网关超时问题,具体解决办法自行百度,有很多教程。

方法2

部分用户不支持修改php配置文件
因为是采集时豆瓣数据太多,可减少采集时的数据。
具体办法
之前的循环判断是:

while($api!=null)

这样就会将所有的数据遍历出来,减少遍历数据就是减少循环次数,将上面的代码修改为:

for($i=0;$i<2;$i++)

这样循环2次,输出两页数据,也就是30条电影数据。

方法3

方法二可以解决问题,但是对于强迫症来说,是非常难受的,比如本人。所以今天想出了下面的方法。

思路不重要直接看文末解决办法

我的思路:

既然之前的数据没有变,为什么非要重新采集数据呢?可不可以将之前的数据拿过来,然后将最新更新的数据与其拼接到一起不就可以了吗?
思路一

  • 豆瓣是通过url分页的,你只要获取到上次采集时的url,就可以使用上次的url接着采集了
  • 现在看看豆瓣的url是什么形式的,输出发现是15 30 45 60,url是递增的,而且每页有15条数据。
  • 这就好办了,用旧json数据,计算出数据的个数n,然后n/15取整,在乘以15,不就是你上次最后采集时的url吗?
  • 然后将新采集的数据,在加上旧数据,减去n/15取余的数据(理论上这部分数据出现两次)不就是新的“我看过的电影” 全部的数据
  • 然而我忘记了,豆瓣更新数据,是在第一页添加,(相当于一个数组,他是在头部插入数据),上次采集的url,是在数组的尾部。例如旧数据:abcdefghij,最后的url是9->j,豆瓣更新数据后是:1111abcdefghij,按照之前的想法实行:在第十位接着采集就变成9->f,新数据是:ghij,拼接上旧数据变成ghijabcdefghij。
  • 代码写到一半,突然想到这个问题,思路一放弃
    思路二
  • 既然是在头部插入新数据,是否可以加一个判断,当采集到旧数据的第一条数据,就结束采集,然后拼接数据。
  • 本来想加一个标识,但发现了下面的代码:

    array("name" => $movie_name, "img" => 'https://images.weserv.nl/?url='.$movie_img, "url" => $movie_url);

  • 可以直接拿name值做判断。

解决办法

  1. 当时间戳超过设置时,先获取旧数据。
  2. $oldData=json_decode(file_get_contents(__DIR__.'/cache/movie.json'))->data;
  3. 将旧数据的第一条数据的name获取到:$oldData[0]->name
  4. 在采集循环中加入判断:if ($oldData[0]->name == $movie_name) return $data;
  5. 将第四步的数据与就数据拼接,使用php函数:array_splice($oldData,0,0,$data);
  6. 由于在json文件不存在是也会file_get_contents(__DIR__.'/cache/movie.json'),所以需要验证
  7. 在不存在文件的判断中加以下代码:

    $file=fopen($FilePath,"w");
    fwrite($file, json_encode(array('time'=>'946656000','data'=>array(array("name" => "", "img" => "".$movie_img, "url" => "")))));

  8. 新建文件时加入空数组的目的是避免“$oldData[0]->name”报错。
  9. 因为json中存在空数组,在页面显示时最后一个电影是空的,影响美观。所以在js中加判断
  10. 在each循环中加入判断:if (item.name == "") {return false;}


不懂上面说的
直接clone代码:https://github.com/SingerLan/douban-wordpress