Replacing Twitter Embeds With Images


I logged into Twitter using a fresh account last week. No followers, no preferences set. The default experience was an unending slurry of racism and porn. I don't care to use Twitter any more. Whatever good that was there is now drowned in a cess-pit of violent filth.

I still have a lot of Tweets embedded on this blog. Using WordPress, it was easy to paste in a link and have it converted to an embed. But I don't want to direct people to a dangerous site.

So here's a somewhat automated way to replace embedded Tweets with screenshots.

Shut up and show me the code!

Demo

Screenshot from Twitter. 2013-11-14T09:50:42.000Z. Terence Eden is on Mastodon (@edent). iOS only! Why not mobile web? MT @SCAS999: Our new app could help save the life of a person suffering cardiac arrest http://t.co/65OaiQ3W78. Reply 2013-11-14T10:15:08.000Z. South Central Ambulance Service (@SCAS999). @edent We'd love a mobile web version. Are you able to help? The app was done for free! Google link here http://t.co/R3xVkLHi3A

Use the Embed Platform

Take the ID of the Tweet you want to convert. Add it on to the end of an embed URl like this - https://platform.twitter.com/embed/Tweet.html?dnt=true&embedId=twitter-widget-0&frame=false&hideCard=false&hideThread=true&lang=en&theme=light&width=550px&id=1092852483033055232

Let's make that a bit more readable:

https://platform.twitter.com/embed/Tweet.html?
   hideCard=false
  &hideThread=true
  &lang=en
  &theme=light
  &width=550px
  &id=1092852483033055232

You can change whether to show a card (the attached image or link), show the preceding message in the thread or not, what UI language to show, dark or light mode, and how wide you want the embed to be.

Use Selenium to automate the screenshot

Using Python, we can use Selenium's Chrome Webdriver to open pages, find elements, and take screenshots:

Python 3 Python 3import time

import io
from PIL import Image

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

#   Chrome's headless options
chrome_options = Options()
chrome_options.add_argument('--headless=new')
chrome_options.add_argument('--window-size=1920,1080')

#   Turn off everything
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument("--disable-infobars")
chrome_options.add_argument("--disable-logging")
chrome_options.add_argument("--log-level=3")

#   Start Chrome
driver = webdriver.Chrome(options=chrome_options)

#   Open the page
driver.get("https://platform.twitter.com/embed/Tweet.html?dnt=true&embedId=twitter-widget-0&frame=false&hideCard=false&hideThread=true&lang=en&theme=light&width=550px&id=1092852483033055232")

#   Twitter is slow!
time.sleep(5)

#   Get the Tweet
tweet = driver.find_element(By.TAG_NAME, "article")
#   Use the parent element for more padding
tweet = driver.execute_script("return arguments[0].parentNode;", tweet)

#   Save as an image
print("Save")
image_binary = tweet.screenshot_as_png
img = Image.open(io.BytesIO(image_binary))
img.save("tweet.png")

Get the alt text

Accessibility is important. Getting the text of the Tweet is as simple as:

Python 3 Python 3#   Get the alt text
alt = tweet.text

But that retrieves all the text - including things like "Copy link to post" and "Read more on X" - because Twitter doesn't believe in semantic HTML. There's also no way to easily get the number of likes and retweets - which might be useful information.

If there are images in the post, it's useful to get their alt text. This is simpler:

Python 3 Python 3images = tweet.find_elements(By.TAG_NAME, "img")
print("\nAlt text of images:")
for img in images:
    alt_text = img.get_attribute("alt")
    if alt_text:
        print(alt_text)

Use The API

There is a better way to get all the text, alt text, and metadata. Use the hidden syndication API! But that's a blog post for another time…

Get the Code

Grab the code from GitHub - and if it is useful to you, please star the repo or leave a friendly comment.

Of course, if we can use the API to get the pure data, perhaps it is possible to make some lovely semantic HTML rather than an image...? 😉


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

3 thoughts on “Replacing Twitter Embeds With Images”

  1. Chris R says:

    Confused! In the black box, is the following string (taken from the URI above) missing?

    "dnt=true&embedId=twitter-widget-0&frame=false"

    Unsure if that bit's accidentally or deliberately missing!

    Reply
    1. @edent says:

      You can use it with or without. I've given the minimum viable example.

      Reply

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">