Ping Test to Popular Websites
First, we define the webiste to ping. This is collection of popular websites + some Indonesian websites.We then define the function to ping the website. Will use the Then we ping all websites. Do it in parallel so it don’t take much time.
Now we calculate the statistics for the successful pings so we can glance some insights.And chart the results.
🗒️ Download (notebook.ipynb)
Show code (37 lines)
websites = [
'google.com',
'facebook.com',
'apple.com',
'amazon.com',
'microsoft.com',
'netflix.com',
'twitter.com',
'instagram.com',
'linkedin.com',
'youtube.com',
'reddit.com',
'wikipedia.org',
'github.com',
'yahoo.com',
'twitch.tv',
'tiktok.com',
'spotify.com',
'whatsapp.com',
'zoom.us',
'discord.com',
'pinterest.com',
'dropbox.com',
'salesforce.com',
'tokopedia.com',
'shopee.co.id',
'zalora.co.id',
'lazada.co.id',
'bukalapak.com',
'blibli.com',
'kompas.com',
'detik.com',
'tribunnews.com',
'cnbcindonesia.com',
'okezone.com',
'liputan6.com',
]ping command.Show code (42 lines)
import subprocess
def ping_website(website):
try:
result = subprocess.run(['ping', '-c', '10', website],
capture_output=True,
text=True,
timeout=10)
if result.returncode == 0:
# Get IP address from first line
first_line = result.stdout.split('\n')[0]
ip_address = first_line.split('(')[1].split(')')[0]
# Get all ping times
ping_times = []
for line in result.stdout.split('\n')[1:-5]: # Skip first and last summary lines
if 'bytes from' in line:
time = float(line.split('time=')[1].split()[0])
ping_times.append(time)
status = 'Success'
else:
ip_address = None
ping_times = []
status = 'Failed'
except subprocess.TimeoutExpired:
ip_address = None
ping_times = []
status = 'Timeout'
except Exception as e:
ip_address = None
ping_times = []
status = f'Error: {str(e)}'
return {
'website': website,
'ip_address': ip_address,
'status': status,
'ping_times_ms': ping_times
}import pandas as pd
import concurrent.futures
results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
future_to_website = {executor.submit(ping_website, website): website for website in websites}
for future in concurrent.futures.as_completed(future_to_website):
result = future.result()
results.append(result)
df = 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’
df[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 |
# Calculate statistics for successful pings only
df_stats = df[df['status'] == 'Success'].copy()
df_stats['min_ms'] = df_stats['ping_times_ms'].apply(lambda x: min(x))
df_stats['max_ms'] = df_stats['ping_times_ms'].apply(lambda x: max(x))
df_stats['avg_ms'] = df_stats['ping_times_ms'].apply(lambda x: sum(x)/len(x))
df_stats['p50_ms'] = df_stats['ping_times_ms'].apply(lambda x: sorted(x)[len(x)//2])
df_stats['std_ms'] = df_stats['ping_times_ms'].apply(lambda x: pd.Series(x).std())import altair as alt
chart = alt.Chart(df_stats).mark_bar().encode(
y=alt.Y('website:N', sort='x'),
x=alt.X('avg_ms:Q', title='Average Ping Time (ms)'),
tooltip=['website', 'avg_ms', 'min_ms', 'max_ms']
).properties(
width=800,
height=400,
title='Average Ping Time by Website - lower is better'
)
chartIt 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)