File tree Expand file tree Collapse file tree 2 files changed +34
-1
lines changed Expand file tree Collapse file tree 2 files changed +34
-1
lines changed Original file line number Diff line number Diff line change @@ -247,6 +247,33 @@ def featured_data(self):
247
247
except Exception :
248
248
return None
249
249
250
+ def unfollowers (self ) -> list [User ]:
251
+ """
252
+ Get all unfollowers by comparing API response and HTML response.
253
+ NOTE: This method can take a long time to run.
254
+
255
+ Based on https://juegostrower.github.io/unfollowers/
256
+ """
257
+ follower_count = self .follower_count ()
258
+
259
+ # regular followers
260
+ usernames = []
261
+ for i in range (1 , 2 + follower_count // 60 ):
262
+ with requests .no_error_handling ():
263
+ resp = requests .get (f"https://scratch.mit.edu/users/{ self .username } /followers/" , params = {"page" : i })
264
+ soup = BeautifulSoup (resp .text , "html.parser" )
265
+ usernames .extend (span .text .strip () for span in soup .select ("span.title" ))
266
+
267
+ # api response contains all-time followers, including deleted and unfollowed
268
+ unfollowers = []
269
+ for offset in range (0 , follower_count , 40 ):
270
+ unfollowers .extend (user for user in self .followers (offset = offset , limit = 40 ) if user .username not in usernames )
271
+
272
+ return unfollowers
273
+
274
+ def unfollower_usernames (self ) -> list [str ]:
275
+ return [user .username for user in self .unfollowers ()]
276
+
250
277
def follower_count (self ):
251
278
with requests .no_error_handling ():
252
279
text = requests .get (
Original file line number Diff line number Diff line change 2
2
import sys
3
3
4
4
5
- def test_import ():
5
+ def test_user ():
6
6
sys .path .insert (0 , "." )
7
7
import scratchattach as sa
8
8
from util import session
9
9
sess = session ()
10
10
11
+ user = sess .connect_user ("faretek1" )
12
+ assert "mochipiyo" in user .unfollower_usernames ()
13
+
11
14
user = sess .connect_user ("ScratchAttachV2" )
12
15
13
16
assert user .id == 147905216
@@ -87,3 +90,6 @@ def test_import():
87
90
status_data = user .ocular_status ()
88
91
assert status_data ["status" ] == "Sample status"
89
92
assert status_data ["color" ] == "#855cd6"
93
+
94
+ if __name__ == '__main__' :
95
+ test_user ()
You can’t perform that action at this time.
0 commit comments