Ping Test to Popular Websites
Show code (37 lines)
1websites = [
2 'google.com',
3 'facebook.com',
4 'apple.com',
5 'amazon.com',
6 'microsoft.com',
7 'netflix.com',
8 'twitter.com',
9 'instagram.com',
10 'linkedin.com',
11 'youtube.com',
12 'reddit.com',
13 'wikipedia.org',
14 'github.com',
15 'yahoo.com',
16 'twitch.tv',
17 'tiktok.com',
18 'spotify.com',
19 'whatsapp.com',
20 'zoom.us',
21 'discord.com',
22 'pinterest.com',
23 'dropbox.com',
24 'salesforce.com',
25 'tokopedia.com',
26 'shopee.co.id',
27 'zalora.co.id',
28 'lazada.co.id',
29 'bukalapak.com',
30 'blibli.com',
31 'kompas.com',
32 'detik.com',
33 'tribunnews.com',
34 'cnbcindonesia.com',
35 'okezone.com',
36 'liputan6.com',
37]
ping
command.Show code (42 lines)
1import subprocess
2
3def ping_website(website):
4 try:
5 result = subprocess.run(['ping', '-c', '10', website],
6 capture_output=True,
7 text=True,
8 timeout=10)
9
10 if result.returncode == 0:
11 # Get IP address from first line
12 first_line = result.stdout.split('\n')[0]
13 ip_address = first_line.split('(')[1].split(')')[0]
14
15 # Get all ping times
16 ping_times = []
17 for line in result.stdout.split('\n')[1:-5]: # Skip first and last summary lines
18 if 'bytes from' in line:
19 time = float(line.split('time=')[1].split()[0])
20 ping_times.append(time)
21
22 status = 'Success'
23 else:
24 ip_address = None
25 ping_times = []
26 status = 'Failed'
27
28 except subprocess.TimeoutExpired:
29 ip_address = None
30 ping_times = []
31 status = 'Timeout'
32 except Exception as e:
33 ip_address = None
34 ping_times = []
35 status = f'Error: {str(e)}'
36
37 return {
38 'website': website,
39 'ip_address': ip_address,
40 'status': status,
41 'ping_times_ms': ping_times
42 }
1import pandas as pd
2import concurrent.futures
3
4results = []
5with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
6 future_to_website = {executor.submit(ping_website, website): website for website in websites}
7 for future in concurrent.futures.as_completed(future_to_website):
8 result = future.result()
9 results.append(result)
10
11df = pd.DataFrame(results)
There are some websites that failed to ping. It is probably because the website is blocking ICMP ping requests as a security measure.
We can see this in the data where some entries have status=‘Failed’ or status=‘Timeout’
1df[df['status'] != 'Success'][['website', 'status']]
website | status | |
---|---|---|
7 | apple.com | Timeout |
8 | linkedin.com | Timeout |
9 | netflix.com | Timeout |
29 | tokopedia.com | Timeout |
34 | detik.com | Timeout |
1# Calculate statistics for successful pings only
2df_stats = df[df['status'] == 'Success'].copy()
3df_stats['min_ms'] = df_stats['ping_times_ms'].apply(lambda x: min(x))
4df_stats['max_ms'] = df_stats['ping_times_ms'].apply(lambda x: max(x))
5df_stats['avg_ms'] = df_stats['ping_times_ms'].apply(lambda x: sum(x)/len(x))
6df_stats['p50_ms'] = df_stats['ping_times_ms'].apply(lambda x: sorted(x)[len(x)//2])
7df_stats['std_ms'] = df_stats['ping_times_ms'].apply(lambda x: pd.Series(x).std())
1import altair as alt
2chart = alt.Chart(df_stats).mark_bar().encode(
3 y=alt.Y('website:N', sort='x'),
4 x=alt.X('avg_ms:Q', title='Average Ping Time (ms)'),
5 tooltip=['website', 'avg_ms', 'min_ms', 'max_ms']
6).properties(
7 width=800,
8 height=400,
9 title='Average Ping Time by Website - lower is better'
10)
11chart
It is interesting to see that the ping latency of various websites fall under 3 ranges.
- Under 1-3 ms
- 10-15 ms
- 180++ ms
I am not sure why the case. There is no pattern that I can see. Whether it is international vs Indonesian websites, or the type of websites (news, e-commerce, etc).
🗒️ Download (notebook.ipynb)