Introduction¶
What is this?¶
malaffinity provides a simple way to calculate affinity (Pearson’s correlation * 100) between a “base” user and another user on MyAnimeList.
Note
The term “base user” refers to the user whose scores other users’ scores will be compared to (and affinities to said scores calculated for).
Just assume the “base user” is referring to you, or whoever will be running your script, unless you’re getting into some advanced mumbo-jumbo, in which case you’re on your own.
malaffinity is meant to be used in bulk, where one user (the “base”)’s scores are compared against multiple people, but there’s nothing stopping you from using this as a one-off.
But why should I bother using this? Doesn’t MAL give me an affinity?¶
Let’s consider what you’d have to do if you wanted MAL to give you an affinity value, and a good estimation as to whether it’s “accurate” or not:
- Create a
requests.Session()
- Make a
GET
request to MAL’s login page - Retrieve the
csrf_token
from one of themeta
headers - Make a
POST
request to the login page, providing a username, password, a bunch of stupid form data, and thecsrf_token
you’ve just obtained - Confirm you are logged in, by seeing if the
is_logged_in
cookie is present in theCookieJar
- Visit a users’ profile
- Look for the affinity value (hint:
.user-compatability-graph .anime .bar-inner
[sic]) - Read its
innerHTML
, retrieve the affinity value, add a case in to get rid of the double-negative that appears on any negative value for some reason - Find how many rated anime you share. The value MAL gives you includes unrated anime,
and PTW stuff. It’s not an accurate indicator
- Visit
/shared.php?u1=you&u2=them
and you find yourself trying to navigate through the dark and murky world of bad HTML table parsing
- Visit
Congrats, you’ve just wasted a few hours of your life, and you’re probably a bit stressed right now. HTML parsing does that to you.
Let’s see how you could handle all this with malaffinity
, assuming your
username is Xinil
and you want to calculate affinity with Luna
:
from malaffinity import MALAffinity
ma = MALAffinity("Xinil")
affinity, shared = ma.calculate_affinity("Luna")
# Do whatever you like with ``affinity`` and ``shared``
print(affinity)
# 37.06659111674594
print(shared) # Note: Is referring to shared, rated anime
# 171
Note
ma
now holds your scores. You can easily call ma.calculate_affinity
on anyone, and you’d get your affinity with them.
If you don’t want your scores to be stored, an option exists for quick, one-off calculations:
import malaffinity
affinity, shared = malaffinity.calculate_affinity("Xinil", "Luna")
# ...
I’m no expert, but the code(s) above looks a lot neater than the alternative would’ve looked.