欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用python绘制人人网好友关系图示例

程序员文章站 2022-05-25 18:23:14
代码依赖:networkx matplotlib 复制代码 代码如下: #! /bin/env python# -*- coding: utf-8 -*-imp...

代码依赖:networkx matplotlib

复制代码 代码如下:

 #! /bin/env python
# -*- coding: utf-8 -*-

import urllib
import urllib2
import cookielib
import re
import cpickle as p
import networkx as nx
import matplotlib.pyplot as plt

__author__ = """reverland (lhtlyy@gmail.com)"""

# control parameters,edit it here
## login
username = 'none'
password = 'none'
## control graphs, edit for better graphs as you need
label_flag = true # whether shows labels.note: configure your matplotlibrc for chinese characters.
remove_isolated = true # whether remove isolated nodes(less than iso_level connects)
different_size = true # nodes for different size, bigger means more shared friends
iso_level = 10
node_size = 40 # default node size

 
def login(username, password):
    """log in and return uid"""
    logpage = "http://www.renren.com/ajaxlogin/login"
    data = {'email': username, 'password': password}
    login_data = urllib.urlencode(data)
    cj = cookielib.cookiejar()
    opener = urllib2.build_opener(urllib2.httpcookieprocessor(cj))
    urllib2.install_opener(opener)
    res = opener.open(logpage, login_data)
    print "login now ..."
    html = res.read()
    #print html

    # get uid
    print "getting user id of you now"
    res = urllib2.urlopen("http://www.renren.com/home")
    html = res.read()
    # print html
    uid = re.search("'ruid':'(\\d+)'", html).group(1)
    # print uid
    print "login and got uid successfully"
    return uid

 
def getfriends(uid):
    """get the uid's friends and return the dict with uid as key,name as value."""
    print "get %s 's friend list" % str(uid)
    pagenum = 0
    dict1 = {}
    while true:
        targetpage = "http://friend.renren.com/getfriendlist.do?curpage=" + str(pagenum) + "&id=" + str(uid)
        res = urllib2.urlopen(targetpage)
        html = res.read()

        pattern = '<a href="http://www\\.renren\\.com/profile\\.do\\?id=(\\d+)"><img src="[\\s]*" alt="[\\s]*[\\s]\\((.*)\\)" />'

        m = re.findall(pattern, html)
        #print len(m)
        if len(m) == 0:
            break
        for i in range(0, len(m)):
            no = m[i][0]
            uname = m[i][1]
            #print uname, no
            dict1[no] = uname
        pagenum += 1
    print "got %s 's friends list successfully." % str(uid)
    return dict1

 
def getdict(uid):
    """cache dict of uid in the disk."""
    try:
        with open(str(uid) + '.txt', 'r') as f:
            dict_uid = p.load(f)
    except:
        with open(str(uid) + '.txt', 'w') as f:
            p.dump(getfriends(uid), f)
        dict_uid = getdict(uid)
    return dict_uid

 
def getrelations(uid1, uid2):
    """receive two user id, if they are friends, return 1, otherwise 0."""
    dict_uid1 = getdict(uid1)
    if uid2 in dict_uid1:
        return 1
    else:
        return 0

 
def getgraph(username, password):
    """get the graph object and return it.
you must specify a chinese font such as `simhei` in ~/.matplotlib/matplotlibrc"""
    uid = login(username, password)
    dict_root = getdict(uid) # get root tree

    g = nx.graph() # create a graph object
    for uid1, uname1 in dict_root.items():
        # encode chinese characters for matplotlib **important**
        # if you want to draw chinese labels,
        uname1 = unicode(uname1, 'utf8')
        g.add_node(uname1)
        for uid2, uname2 in dict_root.items():
            uname2 = unicode(uname2, 'utf8')
            # not necessary for networkx
            if uid2 == uid1:
                continue
            if getrelations(uid1, uid2):
                g.add_edge(uname1, uname2)

    return g

 
def draw_graph(username, password, filename='graph.txt', label_flag=true, remove_isolated=true, different_size=true, iso_level=10, node_size=40):
    """reading data from file and draw the graph.if not exists, create the file and re-scratch data from net"""
    print "generating graph..."
    try:
        with open(filename, 'r') as f:
            g = p.load(f)
    except:
        g = getgraph(username, password)
        with open(filename, 'w') as f:
            p.dump(g, f)
    #nx.draw(g)
    # judge whether remove the isolated point from graph
    if remove_isolated is true:
        h = nx.empty_graph()
        for sg in nx.connected_component_subgraphs(g):
            if sg.number_of_nodes() > iso_level:
                h = nx.union(sg, h)
        g = h
    # ajust graph for better presentation
    if different_size is true:
        l = nx.degree(g)
        g.dot_size = {}
        for k, v in l.items():
            g.dot_size[k] = v
        node_size = [g.dot_size[v] * 10 for v in g]
    pos = nx.spring_layout(g, iterations=50)
    nx.draw_networkx_edges(g, pos, alpha=0.2)
    nx.draw_networkx_nodes(g, pos, node_size=node_size, node_color='r', alpha=0.3)
    # judge whether shows label
    if label_flag is true:
        nx.draw_networkx_labels(g, pos, alpha=0.5)
    #nx.draw_graphviz(g)
    plt.show()

    return g

if __name__ == "__main__":
    g = draw_graph(username, password)