Skip to content

Instantly share code, notes, and snippets.

@stilist
Last active December 23, 2018 03:02
Show Gist options
  • Save stilist/e1406b900f7d295d8c16d77a9000ab44 to your computer and use it in GitHub Desktop.
Save stilist/e1406b900f7d295d8c16d77a9000ab44 to your computer and use it in GitHub Desktop.
Scrape Dribbble likes into JSON that matches the real API's structure (but with some missing data)
// Copyright 2018 Jordan Cole
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
//
// I made this because Dribbble doesn't internally use their likes API to
// construct the page that shows a user's liked items. (They send HTML
// partials.) I can't use their API either, because this is restricted
// functionality: 'This is available only to select applications with our
// approval.' (@see http://developer.dribbble.com/v2/likes/)
//
//
// Run this in the JavaScript console on a user's likes page, e.g.
// https://dribbble.com/simplebits/likes. Make to keep clicking the 'Load more'
// button (or scrolling down) until all the likes are displayed on the page.
JSON.stringify(Array.from(document.querySelectorAll('.dribbbles > li')).map($item => {
// item
const imgHtmlUrl = $item.querySelector(".dribbble-link").href;
const itemId = parseInt(imgHtmlUrl.split(/shots\/(\d+)/)[1], 10);
const $img = $item.querySelector('picture img')
const $teaser = $img.getAttribute('src');
const $hidpi = $item.querySelector('picture source:first-child');
const normalUrl = $teaser.replace(/_teaser/, '');
const $comment = $item.querySelector('.comment');
const date = new Date($item.querySelector('.timestamp').textContent);
// user
const $user = $item.querySelector('.attribution-user');
const $avatar = $user.querySelector('.photo');
const $userLink = $user.querySelector('.url');
const userIdMatch = $avatar.src.match(/users\/(\d+)/);
// Copying the structure from http://developer.dribbble.com/v2/likes/.
return {
id: itemId,
// When the item was liked -- only available in the actual API, as far as I
// can tell.
created_at: null,
shot: {
id: itemId,
title: $item.querySelector('strong').innerText,
// This is truncated on the likes page.
description: $comment ? $comment.innerText : "",
images: {
// Not sure whether this is accurate.
hidpi: $hidpi.srcset === normalUrl ? null : $hidpi.srcset,
normal: normalUrl,
teaser: $teaser,
},
// The data in the HTML only has the date (e.g. 'May 12, 2015'); the API
// has a full ISO 8601 timestamp.
published_at: date.toISOString(),
html_url: imgHtmlUrl,
height: $img.naturalHeight * 2,
width: $img.naturalWidth * 2,
},
user: {
// This will be 'null' if the user's profile has the default avatar.
id: userIdMatch ? parseInt(userIdMatch[1], 10) : null,
name: $avatar.nextSibling.textContent.trim(),
login: $userLink.getAttribute('href').replace('/', ''),
html_url: $userLink.href,
},
}
}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment