Network wide reputation survey
JavaScript (Node.js), 465 bytes
(i,C)=&gt;(p='https://codegolf.stackexchange.com',n=t=a=[],g=(u,c)=&gt;require('https').get(u,r=&gt;r.on('data',d=&gt;i+=d,r.on('end',_=&gt;c(r.headers.location)))))(p+'/users/'+i,l=&gt;g(p+l,_=&gt;g(s=i.match(/ht.+\/s[^&quot;]+\d\/[^?]/)+0,l=&gt;g(new URL(l,s)+'?tab=accounts',_=&gt;i.replace(/unt-[^]+?\n *([\w&amp;].+)[^]+?r&quot;.+?([\d,]+)/g,(_,s,r)=&gt;a.push([s,r=r.split`,`.join``,t-=r,n--]))&amp;&amp;C(a.map(([s,r])=&gt;s.replace(/&amp;#?(.+?);/g,(_,m)=&gt;String.fromCharCode('0'+m|0||38))+` ${r/t*n}x`).join`
`)))))

Function which accepts a the ID as a string and returns the result to a callback.
I tried to make it robust and it should work for any profile as of time of submission with one possible exception: the accounts tab on the network profile contains a profile summary which can be edited by the user so it's possible for a user to write something to fool the regex in their bio.
Explanation
(i,C)=&gt;(p='https://codegolf.stackexchange.com',
// n = count of sites, t = total sum of reputation, a = array of (siteName, rep) tuples
n=t=a=[],
// Function which performs a GET request.
// The body is appended to `i` and the callback is called with the location header.
g=(u,c)=&gt;require('https').get(u,r=&gt;r.on('data',d=&gt;i+=d,r.on('end',_=&gt;c(r.headers.location))))
// Load the user's PPCG profile.
)(p+'/users/'+i,l=&gt;
// Since we only provided the ID and not the name in the URL, it will return a 301 redirect.
// Load the redirect.
g(p+l,_=&gt;
// The first URL on the body to match this regex is the network profile URL of the user.
// Note that this comes before the custom content in the profile
// (which could contain other network profile URLs).
// This request will result in a 301 if the user's name is different on the
// network profile than PPCG, so the first character plus 0 will force a redirect
// because display names are a minimum of 3 characters long.
g(s=i.match(/ht.+\/s[^&quot;]+\d\/[^?]/)+0,l=&gt;
// Load the accounts tab of the network profile.
g(new URL(l,s)+'?tab=accounts',_=&gt;
// Find each site and reputation count.
i.replace(/unt-[^]+?\n *([\w&amp;].+)[^]+?r&quot;.+?([\d,]+)/g,
// Remove the commas from the rep value, populate `a` and add them up for the average.
// decodeURIComponent is annoyingly long but there's no shorter way to correctly display
// sites like the Japanese site which is made solely of URI encoded characters.
(_,s,r)=&gt;a.push([s,r=r.split`,`.join``,t-=r,n--]))&amp;&amp;
// Calculate and print the results.
// There is a lot of bytes dedicated here to unescaping HTML entities because
// unfortunately there's no easy way to correctly display sites like the Japanese site
// which is made solely of HTML encoded characters.
// As far as I can tell the only escapes used in site names are the `&amp;#xXX` style
// and `&amp;amp;`.
C(a.map(([s,r])=&gt;s.replace(/&amp;#?(.+?);/g,(_,m)=&gt;String.fromCharCode(0+m|0||38))+` ${r/t*n}x`).join`
`)))))