linux – Get final URL after curl is redirected – Stack Overflow (plus some Twitter scraping tricks)
Posted by jpluimers on 2025/08/06
Sometimes I need [Wayback/Archive] Redirect Checker | Check your Statuscode 301 vs 302 on the command-line, so cURL to the rescue: [Wayback/Archive] linux – Get final URL after curl is redirected – Stack Overflow. The relevant portions of answers and comments further below.
TL;DR:
Since I prefer verbose command-line arguments (you can find them at the [Wayback/Archive] curl – How To Use on-line man page) especially in scripts this HTTP GET request is what works with Twitter:
% curl --location --silent --output /dev/null --write-out "%{url_effective}\n" https://twitter.com/anyuser/status/20https://x.com/anyuser/status/20
This failed (twitter dislikes HTTP HEAD requests):
% curl --head --location --silent --output /dev/null --write-out "%{url_effective}\n" https://twitter.com/anyuser/status/20https://twitter.com/anyuser/status/20
Notes
Given so many of my scripts now run on zsh, I added the new-line because of command line – Why does a cURL request return a percent sign (%) with every request in ZSH? – Stack Overflow. You can strip that bit.
Note that these do not perform client side redirects, so they do not return the ultimate originating URL https://x.com/jack/status/20 (which was the first ever Tweet on what was back then called twttr) as Twitter on the client-side overwrites window.location.href with the final URL. Similar behaviour for getting the Twitter user handle of a Twitter user ID, more on Twitter tricks below.
Tweet by TweetID trick via [Wayback/Archive] Accessing a tweet using only its ID (and without the Twitter API) – Bram.us.
Further reading (thanks [Wayback/Archive] vise, [Wayback/Archive] Daniel Stenberg, [Wayback/Archive] Ivan, [Wayback/Archive] AndrewF, [Wayback/Archive] Roger Campanera, and [Wayback/Archive] Dave Baird):
A
curl‘s-woption and the sub variableurl_effectiveis what you are looking for.Something like
curl -Ls -o /dev/null -w %{url_effective} https://example.comMore info
-L Follow redirects -s Silent mode. Don't output anything -o FILE Write output to <file> instead of stdout -w FORMAT What to output after completionMore
You might want to add
-I(that is an uppercasei) as well, which will make the command not download any “body”, but it then also uses the HEAD method, which is not what the question included and risk changing what the server does. Sometimes servers don’t respond well to HEAD even when they respond fine to GET.C
Some websites also need a spoofed user agent with
curl -A ...to redirect to the expected location.C
@minseong
-o /dev/nullsuppresses the HTTP response from being outputted anywhere.-sis for curl’s own output (like progress or errors) and specifically does not cover the HTTP response.C
Condiser adding a newline char to have a nice output:
curl -Ls -o /dev/null -w "%{url_effective}\n" https://example.comA
curlcan only follow http redirects. To also follow meta refresh directives and javascript redirects, you need a full-blown browser like headless chrome…
Note that the first link in the answer has moved and rewritten, but the redirect is broken. It is now at [Wayback/Archive] Write out – everything curl.
Some more interesting Twitter link conversions and scraping tricks
I had some Twitter user IDs that I wanted the handles from and vice versa.
Examples are for Twitter user ID 12 for handle jack (Jack Dorsey, original founder of Twitter before it got taken over by Space Karen)
Note that for all the examples you can use http URLs instead of https URLs costing more redirects.
I might write some Bookmarklets for these one day.
Here we go:
Getting the Twitter user handle from a Twitter user ID
From Twitter user ID URL to Twitter user profile URL:
- Start: https://x.com/i/user/12 or https://twitter.com/i/user/12
- Finish: https://x.com/jack and in the past https://twitter.com/jack
From Twitter follow user by ID URL to Twitter follow user by handle URL:
- Start: https://x.com/intent/user?user_id=12 or https://twitter.com/intent/user?user_id=12
- Finish: https://x.com/intent/user?screen_name=jack and in the past https://twitter.com/intent/user?screen_name=jack
Getting the Twitter user ID from a Twitter user handle
- Start: https://x.com/jack or https://twitter.com/jack
- Client side redirect to https://x.com/jack
- Append
/header_photo: https://x.com/jack/header_photo
- Append
- Run this JavaScript:
document.querySelector('img[src*="https://pbs.twimg.com"]').src - The resulting image URL contains Twitter user ID
12right afterhttps://pbs.twimg.com/profile_banners/: https://pbs.twimg.com/profile_banners/12/1742427520/1500×500
To get the ID itself in step 4, the JavaScript gets a tad more complex: document.querySelector('img[src*="https://pbs.twimg.com"]').src.split('https://pbs.twimg.com/profile_banners/')[1].split('/')[0]
Note: you can shortcut from step 2, but be ware that the JavaScript then returns a linkl like https://pbs.twimg.com/profile_images/874985777524092928/77_ho04k_normal.jpg forcing the JavaScript to be a tad longer:
- Start: https://x.com/jack or https://twitter.com/jack
- Client side redirect to https://x.com/jack
- Run this JavaScript:
document.querySelector('img[src*="https://pbs.twimg.com/profile_banners/"]').src - The resulting image URL contains Twitter user ID
12right afterhttps://pbs.twimg.com/profile_banners/: https://pbs.twimg.com/profile_banners/12/1742427520/600×200
To get the ID itself in step 3, the JavaScript gets a tad more complex: document.querySelector('img[src*="https://pbs.twimg.com/profile_banners/"]').src.split('https://pbs.twimg.com/profile_banners/')[1].split('/')[0]
Note the above querySelector paths are way shorter than what browser debugger tools return. For creating these shorter ones, read these three links and use some imagination:
- [Wayback/Archive] Document: querySelector() method – Web APIs | MDN
- [Wayback/Archive] CSS selectors – CSS: Cascading Style Sheets | MDN
- [Wayback/Archive] Attribute selectors – CSS: Cascading Style Sheets | MDN
- [Wayback/Archive] Using document.querySelector() to Find an IMG Element : FirefoxAddons
- [Wayback/Archive] css selectors – CSS hide all images with matching SRC attribute – Stack Overflow (thanks [Wayback/Archive] BoltClock)
- [Wayback/Archive] Selectors Level 3: attribute substrings
The final two three above have examples explaining the third link in more detail.
Note I need to research how to get the results of https://syndication.twitter.com/srv/timeline-profile/screen-name/jack (JSON __NEXT_DATA__ script embedded in HTML) into a parseable form.
Get the Twitter user ID from a Tweet
- Start https://x.com/jack/status/20 or https://twitter.com/jack/status/20 (as explained above the first ever Tweet on Twitter)
- Tweet ID:
20 - CDN URL: https://cdn.syndication.twimg.com/tweet-result?id=20&token=!
- Load and parse the content using JSONPath query
$.user.id_str - For the Twitter user handle use
$.user.name
Note: I didn’t have time yet to figure out how to do this in the client-side in a JavaScript Bookmarklet when starting from the Tweet page.
Hopefully by then I also have time to write Bookmarklets for Twitter image size suffixes reloaded: pbs.twimg.com URL information and the above snippets.
Displaying the Tweet if you only have the Tweet ID
Again using the example Tweet ID 20 (replace your own where needed) and these still work and client-side redirect to the x.com or mobile.x.com domain depending on your platform:
- https://twitter.com/i/web/status/20 or https://x.com/i/web/status/20
- https://mobile.twitter.com/i/web/status/20 or https://mobile.x.com/i/web/status/20
References
The above materials are adapted from this content:
- [Wayback/Archive] Is there a website that can help me find the 1st post on Twitter (or any social media in general)? : Twitter
- [Wayback/Archive] permalinks – URL link to Twitter user with ID, not name – Stack Overflow (thanks [Wayback/Archive] Matt, [Wayback/Archive] Mert S. Kaplan , [Wayback/Archive] Saša Tomislav Mataić, [Wayback/Archive] mzrnsh and [Wayback/Archive] gorner)
- [Wayback/Archive] Overview | Docs | Twitter Developer Platform
- [Wayback/Archive] How to find profile link from user id | Twitter Developers (link suffered from link rot, but the archived versions are OK)
- [Wayback/Archive] Finding Twitter User IDs · GitHub (thanks [Wayback/Archive] kentbrew’s gists · GitHub) in the comments has a solution depending on the internal JSON structures which change more often than the URL structures, so that code fails but at the time of writing this succeeds:
id = JSON.parse(
document.evaluate(
'//script[@type="application/ld+json"]',
document.lastChild,
null,
XPathResult.ANY_TYPE, null).iterateNext().textContent
).mainEntity.identifier;No warranties for the future though (;
- [Wayback/Archive] twitter – Get tweet url having only tweet id – Stack Overflow (thanks [Wayback/Archive] user2980690)
Queries:
- [Wayback/Archive] twitter handle by id – Google Search
- [Wayback/Archive] twitter find user id from handle – Google Search
- [Wayback/Archive] get twitter user id from tweet url – Google Search
- [Wayback/Archive] finding your first tweet – Google Search
- [Wayback/Archive] css selector image by attributes – Google Search
- [Wayback/Archive] chrome extension that shows queryselector for element – Google Search
- [Wayback/Archive] javascript load and parse json – Google Search
Further research
I need to check out these links, as some of their material is likely outdated, and others likely have gems in them:
- [Wayback/Archive] “cdn.syndication.twimg.com” “profile” “widgets.js” – Google Search
- [Wayback/Archive] twitter embed timeline no longer works as of today? – Stack Overflow (from [Wayback/Archive] Angus Grant, [Wayback/Archive] Glauk Abazi and [Wayback/Archive] Talk Nerdy To Me)
- [Wayback/Archive] Defending against XSS with CSP
- [Wayback/Archive] Ayo : webscraping
- [Wayback/Archive] How do you learn about the twitter “API”? · Issue #76 · vercel/react-tweet · GitHub
- [Wayback/Archive] Why CSP Should be carefully crafted: Twitter XSS & CSP Bypass – Blog
- [Wayback/Archive] How to prerender Tweets without using the official Twitter APIs | Stefan Judis Web Development
- [Wayback/Archive] querySelectorAll – Chrome Web Store (not available any more but likely findable through its ID
pdlkbaojmankilmcnolgoijamiemliia) - [Wayback/Archive] SelectorGadget – Chrome Web Store of which currently I am not impressed, but it is slightly better than the various built-in Browser Developer Tools. At least it is open source:
- [Wayback/Archive] How to read an external local JSON file in JavaScript? – Stack Overflow
- [Wayback/Archive] Fetch API – Web APIs | MDN
- [Wayback/Archive] google chrome – How to create a query selector out of a selected element? – Stack Overflow (thanks [Wayback/Archive] codepleb, [Wayback/Archive] Blindman67 and [Wayback/Archive] Illia)
--jeroen
Rate this:
Share this:
- Click to share on Mastodon (Opens in new window) Mastodon
- Click to share on Bluesky (Opens in new window) Bluesky
- Share on Tumblr
- Click to share on Reddit (Opens in new window) Reddit
- Click to share on Threads (Opens in new window) Threads
- Tweet
- Click to share on Telegram (Opens in new window) Telegram
- Click to share on Nextdoor (Opens in new window) Nextdoor
- Click to share on WhatsApp (Opens in new window) WhatsApp
- Click to print (Opens in new window) Print
- Click to email a link to a friend (Opens in new window) Email
Related
This entry was posted on 2025/08/06 at 12:00 and is filed under *nix, *nix-tools, bash, Batch-Files, Bookmarklet, Communications Development, Conference Topics, Conferences, CSS, cURL, Development, Event, HTTP, Internet protocol suite, JavaScript/ECMAScript, Power User, Scripting, SocialMedia, Software Development, TCP, Twitter, Web Browsers, Web Development. Tagged: 76. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
This site uses Akismet to reduce spam. Learn how your comment data is processed.






Leave a comment