Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Created September 7, 2019 19:13
Show Gist options
  • Save kristopherjohnson/de51ee035cffb370baf66f76242c897d to your computer and use it in GitHub Desktop.
Save kristopherjohnson/de51ee035cffb370baf66f76242c897d to your computer and use it in GitHub Desktop.
Python script to unfollow Twitter accounts that have not tweeted in the last 400 days
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Unfollow Quiet Accounts\n",
"\n",
"This script unfollows all the Twitter users who have not tweeted in the last 400 days.\n",
"\n",
"See <https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference> for details of the Twitter API calls used below."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import datetime\n",
"import logging\n",
"import sys\n",
"\n",
"def configure_logging(level=logging.DEBUG):\n",
" \"\"\"Configure the logging module.\n",
" \"\"\"\n",
" logging.basicConfig(\n",
" format='%(asctime)s.%(msecs)03d %(levelname)-7s %(message)s',\n",
" datefmt='%Y-%m-%d %H:%M:%S',\n",
" level=level,\n",
" stream=sys.stderr)\n",
" \n",
"configure_logging()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Dependencies: pip install twitter python-dateutil\n",
"import twitter\n",
"import dateutil.parser"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Go to http://apps.twitter.com/, create an app, and fill in these values:\n",
"consumer_key = 'aaaa'\n",
"consumer_secret = 'bbbb'\n",
"access_token = 'xxxx'\n",
"access_token_secret = 'yyyy'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def twitter_login():\n",
" \"\"\"Connect to Twitter, returning a Twitter instance.\"\"\"\n",
" auth = twitter.OAuth(access_token, access_token_secret, consumer_key, consumer_secret)\n",
" return twitter.Twitter(auth=auth, retry=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tw = twitter_login()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_all_friends(tw):\n",
" \"\"\"Get list of all accounts followed by this account.\"\"\"\n",
" response = tw.friends.list(count=200)\n",
" friends = response['users']\n",
" cursor = response['next_cursor']\n",
" while cursor != 0:\n",
" response = tw.friends.list(count=200,\n",
" cursor=cursor)\n",
" friends.extend(response['users'])\n",
" cursor = response['next_cursor']\n",
" return friends"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"friends = get_all_friends(tw)\n",
"len(friends)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Eliminate friends with no status updates (I'm apparently not following them for their status)\n",
"friends = [friend for friend in friends if 'status' in friend]\n",
"len(friends)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def age_of_status(friend):\n",
" \"\"\"Determine the age of a tweet.\n",
" \n",
" Returns a datetime.timedelta value.\n",
" \"\"\"\n",
" created_at = dateutil.parser.parse(friend['status']['created_at'])\n",
" now = datetime.datetime.now(datetime.timezone.utc)\n",
" return now - created_at"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"quiet_friends = [friend for friend in friends if age_of_status(friend).days > 400]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Unfollow them\n",
"for friend in quiet_friends:\n",
" logging.info(f\"Unfollowing {friend['id']} {friend['name']} ({friend['screen_name']})\")\n",
" tw.friendships.destroy(user_id=friend['id'])\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment