Dribbble API とスクレイピングを組み合わせて検索ワードに関連するShotsの情報を取得する

# 前回
[Dribbble API を Rubyで利用する \- Qiita](https://qiita.com/NaokiIshimura/items/075c19b5bc563799553c)

Dribbble APIを利用してShotsの情報を取得できるようになったものの、Shotsをフリーワードで検索するようなAPIが提供されてないようなので、スクレイピングと組み合わせて検索ワードに関連したShotsの情報が取得できるようにしました。

# 目次
- 解説
    - スクレイピングに利用できそうなデータを探す
        - URL
        - DOM
    - Shotsのidから情報を取得する
    - 検索ワードに関連するShotsの情報を取得する
- 補足
    - Pagination

# 解説

## サンプルプログラム
GitHubでも公開しております。

[Ruby\-Sample\-Dribbble/Qiita at master · NaokiIshimura/Ruby\-Sample\-Dribbble](https://github.com/NaokiIshimura/Ruby-Sample-Dribbble/tree/master/Qiita)

## スクレイピングに利用できそうなデータを探す

### URL

Dribbbleのサイト上で`iphone`というワードで検索を実施すると、
https://dribbble.com/search?q=iphone
というURLがアドレスバーに表示されるので、リクエストのURLにはこれがそのまま利用できそうです。

![dribbble04.png](https://qiita-image-store.s3.amazonaws.com/0/141934/cfdc5b33-2a30-0f52-1a2f-719c47f6f14a.png)

### DOM

ソースを確認するとShotsごとに`id=screenshot-xxxxx`という情報が付与されているので、これを利用することでShotsのidが取得できるようになりそうです。

![dribbble05.png](https://qiita-image-store.s3.amazonaws.com/0/141934/437d44f4-226a-50c5-a722-59fb0024e749.png)

### サンプルプログラム

HTMLの取得に`faraday`, HTMLの解析に`nokogiri`を利用します。

```shell-session
$ gem install faraday
$ gem install nokogiri
```

```ruby:sample4.rb
url = 'https://dribbble.com/search?q=iphone'

require "faraday"

# リクエストを送信
client = Faraday.new
res = client.get do |req|
  req.url url
end

response_body = res.body

require "nokogiri"

# HTMLをparseする
doc = Nokogiri::HTML.parse(response_body, nil, 'utf-8')

# xpathに一致するelementを取得する
selector = "//*[contains(@id, 'screenshot-')]"
elements = doc.xpath(selector)

# 取得したidを格納する配列
dribble_id_list = []

# elementから値を取得する
elements.each do |e|

  # elementからidの値を取得
  element_id = e.attribute("id").value
  # elementのidから不要な文字列を取り除く
  dribble_id = element_id.gsub('screenshot-', '')

  puts 'id : ' + dribble_id

  # 配列に追加
  dribble_id_list.push(dribble_id)

end
```

実行すると検索ワードに関連するShotsのidが取得できます。

```shell-session
$ ruby sample4.rb 

id : 824210
id : 516103
id : 1746065
id : 613490
id : 1115596
id : 2121350
id : 1945593
id : 543645
id : 1109343
id : 606745
id : 2590603
id : 2620936
```

## Shotsのidから情報を取得する

ShosのidがわかればDribbble APIを利用してShotsの情報が取得できます。

```ruby:sample5.rb
# tokenを設定する
#token = '<Client Access Token>'
# idを設定する
id = '824210'
# URLを設定する
url = 'https://api.dribbble.com/v1/shots/' + id

# リクエストを送信
require "faraday"

client = Faraday.new
res = client.get do |req|
  req.url url
  req.headers['Authorization'] = "Bearer #{token}"
end

# レスポンスボディをパースする
require "json"

body = JSON.parse res.body

# Shotsの情報を表示する
p body['title']
p body['images']['hidpi']
```

実行するとShotsの情報が取得できます。

```shell-session
$ ruby sample5.rb 

"waffle iphone icon"
"https://cdn.dribbble.com/users/14268/screenshots/824210/waffle.png"
```

## 検索ワードに関連するShotsの情報を取得する

`sample4.rb`と`sample5.rb`を組み合わせると、検索ワードに関連するShotsの情報を取得できるようになります。
コードがそこそこ長いので、サンプルプログラムはGitHubをご参考いただければと思います。

[Ruby\-Sample\-Dribbble/sample6\.rb at master · NaokiIshimura/Ruby\-Sample\-Dribbble](https://github.com/NaokiIshimura/Ruby-Sample-Dribbble/blob/master/Qiita/sample6.rb)

```shell-session
$ ruby sample6.rb

URL : https://dribbble.com/search?q=iphone
>>> get_dribbble_id
id : 824210
...
>>> get_url_from_id
URL : https://cdn.dribbble.com/users/14268/screenshots/824210/waffle.png
...
```


# 補足

## Pagination

1回のリクエストで取得できるShotsの数は限られていますが、リクエストURLに`page=`を付与することで取得するShotsをスライドさせることができるようになります。

```ruby
url = 'https://dribbble.com/search?q=iphone&page=2'
```