Skip to content

Instantly share code, notes, and snippets.

@USMortality
Last active October 22, 2024 22:39
Show Gist options
  • Save USMortality/0bd9f3389f876fc0cb36cec3301471f3 to your computer and use it in GitHub Desktop.
Save USMortality/0bd9f3389f876fc0cb36cec3301471f3 to your computer and use it in GitHub Desktop.
Get X Stats
#!/bin/sh
### Prerequisites: MacOS: Homebrew & NodeJS
# brew install n # Homebrew: https://brew.sh
# n install lts
npm install -g playwright
playwright install chromium
export NODE_PATH=$(npm root -g)
#handle="usmortality"
#tweet="1848379918570127781"
node -e "
const { chromium } = require('playwright');
const convertToNumber = (value) =>
value === undefined || value === '' ? 0 : value.includes('K') ? parseFloat(value.replace(/,/g, '')) * 1000 :
value.includes('M') ? parseFloat(value.replace(/,/g, '')) * 1000000 : parseFloat(value.replace(/,/g, '')) || 0;
const safeDivide = (numerator, denominator) =>
denominator === 0 ? 0 : (numerator / denominator).toFixed(2);
(async () => {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'
});
const page = await context.newPage();
try {
await page.goto(\`https://x.com/${handle}\`, { waitUntil: 'domcontentloaded' });
const userContent = await page.textContent('div[data-testid="UserName"] ~ div:nth-of-type(5)').catch(() => '');
await page.goto(\`https://x.com/${handle}/status/${tweet}\`, { waitUntil: 'domcontentloaded' });
const viewsLocator = page.locator('article div span').filter({ hasText: /Views/i });
const viewsText = await viewsLocator.first().textContent();
const views = convertToNumber(viewsText.match(/([\d,.KM]+)/)?.[1] || '0');
const tweetContent = await page.textContent('article div:nth-of-type(5)').catch(() => '');
const following = convertToNumber(userContent.match(/([\d,.KM]+)(?= Following)/)?.[1] || '0');
const followers = convertToNumber(userContent.match(/([\d,.KM]+)(?= Followers)/)?.[1] || '0');
const likes = convertToNumber(tweetContent.match(/([\d,.KM]+)(?= Likes)/)?.[1] || '0');
const retweets = convertToNumber(tweetContent.match(/([\d,.KM]+)(?= Reposts)/)?.[1] || '0');
const bookmarks = convertToNumber(tweetContent.match(/([\d,.KM]+)(?= Bookmarks)/)?.[1] || '0');
const followersInThousands = safeDivide(followers, 1000);
const likesPerThousandViews = safeDivide(likes, views / 1000);
const retweetsPerThousandViews = safeDivide(retweets, views / 1000);
const bookmarksPerThousandViews = safeDivide(bookmarks, views / 1000);
const followRatio = safeDivide(following, followersInThousands);
const viewsPerFollower = safeDivide(views, followers);
const result = \`
Following Followers Following/1kFollowers Views Views/Follower Likes Likes/1kViews RTs RTs/1kViews Bookmarks Bookmarks/1kViews
\${following} \${followers} \${followRatio} \${views} \${viewsPerFollower} \${likes} \${likesPerThousandViews} \${retweets} \${retweetsPerThousandViews} \${bookmarks} \${bookmarksPerThousandViews}
\`;
console.log(result.trim());
} catch (error) {
console.error('Error:', error.message);
} finally {
await browser.close();
}
})();
" | column -t
@USMortality
Copy link
Author

1

@USMortality
Copy link
Author

export handle="hodgetwins"; export tweet="1848451930336485873"; curl -s https://gist.githubusercontent.com/USMortality/0bd9f3389f876fc0cb36cec3301471f3/raw/x_stats.sh | bash

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