My client needed to automate Flickr image search. They wanted a PHP script that uses Flickr API to scrape and save pictures related to keywords with creative commons license.

Also they needed to be able to filter pictures by size and number of favorites (likes). Here is the solution.

I decided to start with something simple, for example a page that searches and shows pictures and information without saving. Like this.

[caption id=”attachment_676” align=”alignnone” width=”660”]scraping flickr images in php scraping flickr images in php[/caption]

At first I created an app and googled for a decent Flicker API wrapper in PHP. Alas, I couldn’t find anything useful.

Some libraries just didn’t work right out of the box. Moreover they didn’t report any errors at all. And I didn’t feel like debugging them either. Others looked too overengineered for such a simple task.

So I used this simple example and rolled my own Flickr API wrapper.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class FlickrApi {
private $apiKey = '';
public function __construct($apiKey) {
$this->apiKey = $apiKey;
}
public function api($params) {
$params['api_key'] = $this->apiKey;
$params['format'] = 'json';
$params['nojsoncallback'] = 1;
$encoded_params = array();
foreach ($params as $k => $v){
$encoded_params[] = urlencode($k).'='.urlencode($v);
}
$url = "https://api.flickr.com/services/rest/?".implode('&', $encoded_params);
$rsp = file_get_contents($url);
$rsp_obj = json_decode($rsp, 1);
return $rsp_obj;
}
}

Nothing fancy here, just doing requests to Flickr API and returning results. Simple and just works.

And here is example that searches pictures by tag provided, and shows only big ones with number of favorites >= 5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
include_once __DIR__.'/FlickrApi.php';
function getPhotos($tags) {
$flickr = new FlickrApi('PUT YOUR API KEY HERE');
$params = array(
'method' => 'flickr.photos.search',
'tags' => $tags,
'license' => '4,5,6,7',
'content_type' => 1, //photos only
'extras' => 'url_l,url_sq',
'media' => 'photos',
'per_page' => 100,
'sort' => 'relevance',
);
$photos = $flickr->api($params); // get photos
$result = array();
foreach($photos['photos']['photo'] as $p) {
if(!isset($p['url_l'])) continue; // doesn't have big image, skip it
$params = array(
'method' => 'flickr.photos.getFavorites',
'photo_id' => $p['id'],
);
$favs = $flickr->api($params);
$favs = $favs['photo']['total']; // total count of favorites
if($favs >= 5) {
$params = array(
'method' => 'flickr.photos.getInfo',
'photo_id' => $p['id'],
);
$photo = $flickr->api($params);
$data = array();
$data['url_l'] = $p['url_l'];
$data['url_sq'] = $p['url_sq'];
$data['favorites'] = $favs;
$data['owner'] = $photo['photo']['owner']['username'];
$data['title'] = $photo['photo']['title']['_content'];
$data['description'] = $photo['photo']['description']['_content'];
$data['url'] = $photo['photo']['urls']['url'][0]['_content'];
$result[] = $data;
}
if(count($result) >= 10) return $result;
}
return $result;
}
$tags = isset($_GET['tag']) ? $_GET['tag'] : 'landscape';
$res = getPhotos($tags);

You can check full example in the Github repo.