Project: r/place timelapses - Chapter1
Background:⌗
r/place is a recurring collaborative project and social experiment hosted on the content aggregator site Reddit. The 2017 experiment involved an online canvas located at a subreddit called r/place. Registered users could edit the canvas by changing the color of a single pixel with a replacement from a 16-color palette. After each pixel was placed, a timer prevented the user from placing any more pixels for a period of time varying from 5 minutes.
First step: getting the canvas images.⌗
2023 event started and I didnt plan to be a part of it, but as I made a few timelapses last year some people asked if I could create new ones.
I didn’t find a datadump of the recorded images (yet) so I looked to place-atlas to see if I could find their source.
Didnt find it, so decided to see if I could data dump their images with a hacky python script.
Started with inspecting their site trough firefox + inspect + network and moving the slider to see what popped up.
It seemed like their time-slider was loading images with javascript, not staticly declared in the source code.. Though the filenames were the epoch-time of the timestamp tooltip!
The slides had URL-hooks, numbered 0-260, that’s possible to iterate.
from selenium import webdriver
from bs4 import BeautifulSoup
from datetime import datetime
import time
import calendar
import requests
import shutil
logfile = open("skipped", "w") # file to log skipped slides
# # Uncomment to retry with list of skipped slides, comment other 'for'-start:
# skipped = open("skipped", "r")
# for number in skipped.readlines(): # retrying
for number in range(1,259): # iterate over the slides, skipping first and last (blank)
try:
driver = webdriver.Firefox()
print("Current slide:{}".format(number))
url = "https://2023.place-atlas.stefanocoding.me/#/{}".format(number)
driver.get(url)
time.sleep(3) # sleep to properly load the page and JS-code
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
# find the timestamp from slider tooltip
timestamp = soup.find("div", {"class": "bg-body p-1 rounded"})
driver.quit()
# Get url for source image by converting timestamp to unixtimeUTC:
img_date = datetime.strptime(timestamp.text, "%a, %d %b %Y %H:%M:%S %Z")
img_unixtime = calendar.timegm(img_date.utctimetuple())
img_url = "https://2023.place-atlas.stefanocoding.me/_img/canvas/main/{}.png".format(img_unixtime)
# Grab the image and save it
filename = "{}_atlas.png".format(number)
res = requests.get(img_url, stream = True)
if res.status_code == 200:
with open(filename,'wb') as f:
shutil.copyfileobj(res.raw, f)
except:
# logging skipped slides if it times out or any other error, to try again later
print("Skipping slide {}".format(number))
logfile.write("{}\n".format(number)) # log skipped number
continue
logfile.close()
That’s the first step of getting raw image data to work with. Stealing them from place-atlas.
Continue reading: Chapter 2