#!/usr/bin/env python3##UserParameter=custom.page.load[*],/opt/sh/zbx_discover_site/page-load.py $1#importrequestsfrombs4importBeautifulSoupimportreimporturllib.parseimportsysfromtimeimporttimedebug=1classLoady:files={'js':{},'css':{},'img':{}}def__init__(self,url,headers={}):ifnotisinstance(headers,dict):raiseValueError('Headers argument must be dict instance')self.url=urlself.total_time=0self.js=[]self.css=[]self.img=[]self.http_headers=headersself.soup=Noneself.total_size=0def_get(self,tag):"""Gets all site additional files and prepares their URL to be loaded"""# Get current URL datadomain_scheme,domain,_,_,_,_=urllib.parse.urlparse(self.url)urls=[]iftag=='script':# Get all script tag with src attribute# print(self.soup.find_all( 'script', { 'src' : re.compile( r'.*' ) } ))tags=self.soup.find_all('script',{'src':re.compile(r'.*')})eliftag=='img':# print(self.soup.find_all( 'img', { 'src' : re.compile( r'.*' ) } ))tags=self.soup.find_all('img',{'src':re.compile(r'.*')})# elif tag is 'i':# print(tags = self.soup.find_all('i', {'style': re.compile(r'.*')}))# tags = self.soup.find_all('i', {'style': re.compile(r'.*')})else:# Get all link tag with rel=stylesheet# print(self.soup.find_all( 'link', { 'rel' : 'stylesheet' } ))tags=self.soup.find_all('link',{'rel':'stylesheet'})foreach_tagintags:# Get the value of src or hrefval=each_tag['src']iftag=='script'ortag=='img'elseeach_tag['href']#val = ''#if tag is 'script' or tag is 'img':# val = each_tag['src']#else:# val = each_tag['href']# parse the URL of the gotten URLurl=urllib.parse.urlparse(val)ifnoturl[0]andurl[1]:# If URL has no scheme but has domain name, we assume it is a URL that supports HTTP(S). We just append the main site scheme to itifnotval.startswith("//"):urls.append('{0}://{1}'.format(domain_scheme,val))else:urls.append('{0}:{1}'.format(domain_scheme,val))elifnoturl[1]:# URL has no domain, its a relative path. Append the domain name to itifnotval.startswith("/"):urls.append('{0}://{1}/{2}'.format(domain_scheme,domain,val))else:urls.append('{0}://{1}{2}'.format(domain_scheme,domain,val))else:# Its an absolute path, no issues bro!urls.append(val)iftag=='script':self.js=urlseliftag=='img':self.img=urlselse:self.css=urlsdef_load(self,t):"""Load the gotten links, check for response time and size. Appends it to self.files object"""_link_obj=[]ift=='script':_link_obj=self.jselift=='img':_link_obj=self.imgelse:_link_obj=self.css# for link in ( self.js if t is 'script' else self.css ):forlinkin(_link_obj):ifdebug==1:print(link)try:start=time()r=requests.get(link)end=time()# Calculate the total time taken to load linkresponse_time=(end-start)# Page loaded successfullyifr.status_code==200:# Get the size of page contentsize=sys.getsizeof(r.content)ift=='img'elsesys.getsizeof(r.text)# Add results to self.files objectobj=''ift=='style':obj='css'elift=='img':obj='img'else:obj='js'self.files[obj][link]={'byte_size':size,'load_time':response_time}# Sum up total time to the existing load timeself.total_time+=response_timeself.total_size+=sizeexceptExceptionase:ifdebug==1:print(e,link)continuedefget(self):"""Loads the main website, calculate response time, page size and get additional files in site"""start=time()r=requests.get(self.url,headers=self.http_headers)stop=time()ifr.status_code==200:response=r.textself.total_time=self.total_time+(stop-start)self.total_size+=sys.getsizeof(response)self.soup=BeautifulSoup(response,'html.parser')self._get('script')self._load('script')self._get('style')self._load('style')self._get('img')self._load('img')load=Loady(sys.argv[1],headers={'User-Agent':'zabbix pageload monitor'})#load = Loady( sys.argv[1], headers={ 'User-Agent' : 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0' })load.get()#print("{TIME:\"",load.total_time,"\"}",sep='')# print("%.3f"%load.total_time)print(load.total_size)# total load size# print( load.files ) #load file and load size