Skip to content

Instantly share code, notes, and snippets.

@Crissov
Last active August 15, 2018 16:34
Show Gist options
  • Save Crissov/5bbf9704995317c20955ab2d0caf1045 to your computer and use it in GitHub Desktop.
Save Crissov/5bbf9704995317c20955ab2d0caf1045 to your computer and use it in GitHub Desktop.
Scrape Facebook emojis
let content_security_policy = "script-src 'self'; object-src 'self' https://www.facebook.com/"; // for running in Chrome's JS console
/* Let’s see which Unicode 10.0 emojis Facebook already supports.
<https://github.com/Crissov/unicode-proposals/issues/254#issuecomment-284831620> */
let myEmojis = new Map([
['1f6f7', 'U+1F6F7 🛷 SLED'],
['1f6f8', 'U+1F6F8 🛸 FLYING SAUCER'],
['1f91f', 'U+1F91F 🤟 I LOVE YOU HAND SIGN'],
['1f928', 'U+1F928 🤨 FACE WITH ONE EYEBROW RAISED'],
['1f929', 'U+1F929 🤩 GRINNING FACE WITH STAR EYES'],
['1f92a', 'U+1F92A 🤪 GRINNING FACE WITH CRAZY EYES'],
['1f92b', 'U+1F92B 🤫 FACE WITH FINGER COVERING CLOSED LIPS'],
['1f92c', 'U+1F92C 🤬 SERIOUS FACE WITH SYMBOLS COVERING MOUTH'],
['1f92d', 'U+1F92D 🤭 SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH'],
['1f92e', 'U+1F92E 🤮 FACE WITH OPEN MOUTH VOMITING'],
['1f92f', 'U+1F92F 🤯 SHOCKED FACE WITH EXPLODING HEAD'],
['1f931', 'U+1F931 🤱 BREAST-FEEDING'],
['1f932', 'U+1F932 🤲 PALMS UP TOGETHER'],
['1f94c', 'U+1F94C 🥌 CURLING STONE'],
['1f95f', 'U+1F95F 🥟 DUMPLING'],
['1f960', 'U+1F960 🥠 FORTUNE COOKIE'],
['1f961', 'U+1F961 🥡 TAKEOUT BOX'],
['1f962', 'U+1F962 🥢 CHOPSTICKS'],
['1f963', 'U+1F963 🥣 BOWL WITH SPOON'],
['1f964', 'U+1F964 🥤 CUP WITH STRAW'],
['1f965', 'U+1F965 🥥 COCONUT'],
['1f966', 'U+1F966 🥦 BROCCOLI'],
['1f967', 'U+1F967 🥧 PIE'],
['1f968', 'U+1F968 🥨 PRETZEL'],
['1f969', 'U+1F969 🥩 CUT OF MEAT'],
['1f96a', 'U+1F96A 🥪 SANDWICH'],
['1f96b', 'U+1F96B 🥫 CANNED FOOD'],
['1f992', 'U+1F992 🦒 GIRAFFE FACE'],
['1f993', 'U+1F993 🦓 ZEBRA FACE'],
['1f994', 'U+1F994 🦔 HEDGEHOG'],
['1f995', 'U+1F995 🦕 SAUROPOD'],
['1f996', 'U+1F996 🦖 T-REX'],
['1f997', 'U+1F997 🦗 CRICKET'],
['1f9d0', 'U+1F9D0 🧐 FACE WITH MONOCLE'],
['1f9d1', 'U+1F9D1 🧑 ADULT'],
['1f9d2', 'U+1F9D2 🧒 CHILD'],
['1f9d3', 'U+1F9D3 🧓 OLDER ADULT'],
['1f9d4', 'U+1F9D4 🧔 BEARDED PERSON'],
['1f9d5', 'U+1F9D5 🧕 PERSON WITH HEADSCARF'],
['1f9d6', 'U+1F9D6 🧖 PERSON IN STEAMY ROOM'],
['1f9d7', 'U+1F9D7 🧗 PERSON CLIMBING'],
['1f9d8', 'U+1F9D8 🧘 PERSON IN LOTUS POSITION'],
['1f9d9', 'U+1F9D9 🧙 MAGE'],
['1f9da', 'U+1F9DA 🧚 FAIRY'],
['1f9db', 'U+1F9DB 🧛 VAMPIRE'],
['1f9dc', 'U+1F9DC 🧜 MERPERSON'],
['1f9dd', 'U+1F9DD 🧝 ELF'],
['1f9de', 'U+1F9DE 🧞 GENIE'],
['1f9df', 'U+1F9DF 🧟 ZOMBIE'],
['1f9e0', 'U+1F9E0 🧠 BRAIN'],
['1f9e1', 'U+1F9E1 🧡 ORANGE HEART'],
['1f9e2', 'U+1F9E2 🧢 BILLED CAP'],
['1f9e3', 'U+1F9E3 🧣 SCARF'],
['1f9e4', 'U+1F9E4 🧤 GLOVES'],
['1f9e5', 'U+1F9E5 🧥 COAT'],
['1f9e6', 'U+1F9E6 🧦 SOCKS']
]);
/** EmojiStaticConfig, EmojiConfig */
var defaultSize = 32;// 64 does not work, 128 only works for emojis from Unicode 10
var pixelRatio = 3;// values of 1, 1.5, 2 and 3 are working, possibly others as well, but not 2.5
var schemaAuth = "https:\/\/www\.facebook\.com\/images\/emoji\.php\/v8"; // the digit at the end does not seem to matter much, FB uses `7` or `8`
var fileExt = ".png";
var checksumBase = 317426846;
var supportedSizes = {
"16": "DP16",
"18": "DP18",
"20": "DP20",
"24": "DP24",
"28": "DP28",
"30": "DP30",
"32": "DP32",
"64": "DP64",
"128": "DP128"
};
var types = {
FBEMOJI: "f",
FB_EMOJI_EXTENDED: "e",
MESSENGER: "z",
UNICODE: "u"
}
var FBEMOJI = "f";
var FB_EMOJI_EXTENDED = "e";
var MESSENGER = "z";
var UNICODE = "u";
/**
* Facebook emoji URL checksum
* @param string codepoints = "{single-digit pixel ratio}/"
* + "{decimal pixel width/height}/"
* + "{lowercase hexadecimal Unicode positions, separated by underscores}.png"
* = `\d/\d{2,3}/[a-f\d_]+\.png` (lax RX)
* = `[12]/(16|18|20|24|28|30|32|64|128)/[a-f\d]{4,5}(_[a-f\d]{4,5})*\.png` (stricter RX)
* @param int base = 317426846 (default)
* @returns string of 2 hexadecimal digits
*/
function checksum(path, base) { /* i(k, l) */
// path = unescape(encodeURIComponent(path));
/** `unescape()`: `&amp;` → `&`, `&lt;` → `<`, `&gt;` → `>`, `&quot;` → `"`, `&#x27;` → `'` */
for (var pos = 0; pos < path.length; pos++) {
base = (base << 5) - base + path.charCodeAt(pos);
base &= 4294967295;
}
return (base & 255).toString(16);
}
function getURL(codepoints, size, type) { /* j(k, l, m) */
size in supportedSizes || defaultSize;
var path = pixelRatio + '/' + size + '/' + codepoints + fileExt;
var check = checksum(path, checksumBase);
return schemaAuth + '/' + type + check + '/' + path;
}
function getMessengerURL(codepoints, size) { /* k(l, m) */
return getURL(codepoints, size, types.MESSENGER);
}
function getFBEmojiURL(codepoints) { /* k(l) */
var size = arguments.length <= 1 || arguments[1] === undefined ? defaultSize : arguments[1];
return getURL(codepoints, size, types.FBEMOJI);
}
function getFBEmojiExtendedURL(codepoints) { /* k(l) */
var size = arguments.length <= 1 || arguments[1] === undefined ? defaultSize : arguments[1];
return getURL(codepoints, size, types.FB_EMOJI_EXTENDED);
}
/** Output HTML and automatically click on each link */
function FBemoji(codepoints, alt) {
var address = getFBEmojiURL(codepoints);
var download = document.createElement("a");
download.setAttribute("id", codepoints);
download.setAttribute("download", alt + ".png");
download.setAttribute("title", alt);
download.setAttribute("href", address);
var thumb = document.createElement("img");
thumb.setAttribute("src", address);
thumb.setAttribute("alt", alt);
thumb.setAttribute("title", codepoints);
download.appendChild(thumb);
return document.body.appendChild(download);
}
var title = document.getElementsByTagName("title")[0];
title.textContent = "Facebook emoji image scraper";
var body = document.getElementsByTagName("body")[0];
body.textContent = ""; // clear all existing body content
for (let [codepoint, name] of myEmojis) {
var node = FBemoji(codepoint, name);
node.click();
}
@dhjw
Copy link

dhjw commented Aug 15, 2018

Apparently for the emoticons PACMAN :v LIKE (y) and FACE_WITH_COLON_THREE :3 the capitalized name should be used as the codepoint and the type set to "e".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment