18
loading...
This website collects cookies to deliver better user experience
pip3 install pyrogram
)pip3 install networkx
)from pyrogram import Client
import pickle
import asyncio
api_id = 123 # your API ID here
api_hash = "1234567890abcdef1234567890abcdef" # your API hash here
c = Client("my_pyrogram_session", api_id, api_hash)
async def main():
await c.start()
dialogs = [i async for i in c.iter_dialogs()]
chat_members = {}
for i in dialogs:
print("Loading", i.chat.id, i.chat.first_name or i.chat.title)
try:
members = [j async for j in i.chat.iter_members()]
chat_members[i.chat.id] = members
print(len(members), "member(s) loaded.")
except Exception as e:
print(e)
with open("dialogs.pkl", "wb") as f:
pickle.dump(dialogs, f)
with open("members.pkl", "wb") as f:
pickle.dump(chat_members, f)
asyncio.run(main())
import pickle
import networkx as nx
MY_ID = 12345678
# Load data
dialogs = pickle.load(open("dialogs.pkl", "rb"))
members = pickle.load(open("members.pkl", "rb"))
# Build graph
g = nx.Graph()
for k, v in members.items():
for m in v:
if m.user.id != MY_ID:
g.add_edge(k, m.user.id)
g2 = g.copy()
for k, v in nx.degree(g):
if v == 1:
g2.remove_node(k)
from networkx.drawing.nx_pydot import write_dot
write_dot(g2, 'graph.dot')
graph.dot
file in your working directory with Gephi, and you should be able to see the graph shown in the window. Usually, it will automatically generate a layout for you. If you are not satisfied with it, I’d recommend to reset it with Random Layout and build a new layout again with ForceAtlas 2.dmap = {i.chat.id: i.chat for i in dialogs}
for i in members.values():
for j in i:
if j.user.id not in dmap:
dmap[j.user.id] = j.user
for i in g2.nodes.keys():
if i in dmap:
t = None
try:
if dmap[i].is_deleted:
g2.nodes[i]["label"] = "%DELETED_ACCOUNT%"
continue
except:
pass
try:
t = dmap[i].title
if t:
g2.nodes[i]["label"] = dmap[i].title
continue
except:
pass
try:
if not t:
if dmap[i].first_name or dmap[i].last_name:
t = f"{dmap[i].first_name} {dmap[i].last_name or ''}".strip()
g2.nodes[i]["label"] = t
continue
except:
pass
if not t:
print(i, "has no name")
else:
print(i, "is not found")
import unicodedata
def normalize_name(s):
s = unicodedata.normalize("NFKC", s)
s = list(s)
for idx, i in enumerate(s):
cat = unicodedata.category(i)
if cat[0] in "CMZPS" or cat == "Lm":
s[idx] = "_"
return "".join(s)
for i in g2.nodes:
if "label" in g2.nodes[i]:
g2.nodes[i]["label"] = normalize_name(g2.nodes[i]["label"])
print([len(c) for c in nx.connected_components(g)])
dg = g.degree()
sdg = sorted(dict(dg2).items(), key=lambda a: a[1], reverse=True)
print(sdg[:100])
from itertools import combinations
pair_common = []
for i, j in combinations(members.keys(), 2):
try:
inb = set(g.neighbors(i))
jnb = set(g.neighbors(j))
if len(inb) < 4 or len(jnb) < 4:
continue
res = len(inb & jnb)
pair_common.append(tuple(i, g2.nodes[i]["label"], j, g2.nodes[i]["label"], res))
except:
continue
pair_common.sort(key=lambda a: a[4], reverse=True)
print(pair_common[:100])
import graphistry
graphistry.store_token_creds_in_memory(False)
graphistry.register(api=3, protocol="https", server="hub.graphistry.com",
token="YOUR_TOKEN_GOES_HERE")
graphistry.bind(source='src', destination='dst', node='nodeid', point_title="label").plot(g2)