├── urls.xlsx ├── README.md └── lighthouse.py /urls.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frozen-dev71/SEO-Lighthouse-Multiple-URLs/main/urls.xlsx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SEO: Run multiple URLs and get ligthhouse V6 Scores. 2 | 3 | Run lighthosue with multiple URLs and get different scores all in one master csv file. 4 | 5 | ## Getting Started 6 | 7 | Previously we had a different script that urn a bash file and used node lightouse. I re-did the script and made it less complicated. Now we can run evertyhgin just from python using a csv file 8 | 9 | ### Prerequisites 10 | ``` 11 | pandas 12 | requests 13 | ``` 14 | 15 | ### Running Script 16 | 17 | Once we install the prerequistes we can go ahead and add the URLs we want to get the scores on urls.xlsx. 18 | 19 | After that we go into the command line and run: 20 | 21 | 22 | 23 | ``` 24 | python lighthouse.py 25 | ``` 26 | 27 | Once finished this will output one master file with all your scores for your different URLs 28 | 29 | **For Example:** 30 | 31 | | url | Performance | accessibility | best-practices | seo | pwd | 32 | |------------------------------------ |------------- |--------------- |---------------- |----- |----- | 33 | | https://www.kburchardt.com | 80 | 90 | 100 | 100 | 100 | 34 | | https://www.uselessthingstobuy.com | 89 | 91 | 100 | 99 | 100 | 35 | 36 | 37 | 38 | ## Contributing 39 | 40 | If you want to contribute please open an issue or send me an email hello@kburchardt.com. If not just give me a star. 41 | 42 | ## Authors 43 | 44 | * **Konrad Burchardt** - *Initial work* - [Sundios](https://github.com/sundios) 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /lighthouse.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import pandas as pd 3 | from datetime import date 4 | 5 | url_list = pd.read_excel('urls.xlsx') 6 | device = 'mobile' #Select here device it can be mobile or desktop 7 | category = 'performance' 8 | today = date.today().strftime("%Y-%m-%d") 9 | 10 | 11 | def webcorevitals(url_list,device,category,today): 12 | df_list = [] 13 | for url in url_list['URL']: 14 | print(url) 15 | 16 | 17 | #making api call for URL 18 | response = requests.get("https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url="+url+"&strategy="+device+"&category="+category) 19 | 20 | 21 | #saving response as json 22 | data = response.json() 23 | 24 | print('Running URL #',url) 25 | 26 | test = url 27 | date = today 28 | 29 | # ============================================================================= 30 | # #Getting Metrics 31 | # 32 | # ============================================================================= 33 | 34 | try: 35 | data = data['lighthouseResult'] 36 | except KeyError: 37 | print('no Values') 38 | data = 'No Values.' 39 | pass 40 | #First Contentful Paint 41 | try: 42 | #First Contentful Paint 43 | fcp = data['audits']['first-contentful-paint']['displayValue'] 44 | except KeyError: 45 | print('no Values') 46 | fcp = 0 47 | pass 48 | 49 | #Largest Contentful Paint 50 | try: 51 | 52 | lcp = data['audits']['largest-contentful-paint']['displayValue'] 53 | except KeyError: 54 | print('no Values') 55 | lcp = 0 56 | pass 57 | 58 | #Cumulative layout shift 59 | try: 60 | 61 | cls = data['audits']['cumulative-layout-shift']['displayValue'] 62 | except KeyError: 63 | print('no Values') 64 | cls = 0 65 | pass 66 | 67 | try: 68 | #Speed Index 69 | si = data['audits']['speed-index']['displayValue'] 70 | except KeyError: 71 | print('no Values') 72 | si = 0 73 | pass 74 | try: 75 | 76 | #Time to Interactive 77 | tti = data['audits']['interactive']['displayValue'] 78 | except KeyError: 79 | print('no Values') 80 | tti = 0 81 | try: 82 | #Total Blocking Time 83 | tbt= data['audits']['total-blocking-time']['displayValue'] 84 | except KeyError: 85 | print('no Values') 86 | tbt = 0 87 | pass 88 | 89 | try: 90 | #score 91 | score = data['categories']['performance']['score'] 92 | except KeyError: 93 | print('no Values') 94 | pass 95 | 96 | #list with all values 97 | values = [test, score,fcp,si,lcp,tti,tbt,cls,date] 98 | 99 | # create DataFrame using from score list 100 | df_score = pd.DataFrame( values ) 101 | 102 | #transpose so its columns 103 | df_score = df_score.transpose() 104 | 105 | #appending scores to empty df outside for loop 106 | df_list.append(df_score) 107 | 108 | #concatinating list of dataframe into one 109 | df = pd.concat(df_list) 110 | 111 | #naming columns 112 | df.columns = ['URL','Score', 'FCP','SI','LCP','TTI','TBT','CLS','Date'] 113 | 114 | #removing s from LCA so we can get mean also transforming it to float so we can get mean values 115 | df['LCP'] = df['LCP'].astype(str).str.replace(r's', '').astype(float) 116 | df['FCP'] = df['FCP'].astype(str).str.replace(r's', '').astype(float) 117 | df['SI'] = df['SI'].astype(str).str.replace(r's', '').astype(float) 118 | df['TTI'] = df['TTI'].astype(str).str.replace(r's', '').astype(float) 119 | df['TBT'] = df['TBT'].astype(str).str.replace(r'ms', '') 120 | df['TBT'] = df['TBT'].astype(str).str.replace(r',', '').astype(float) 121 | df['Score'] = df['Score'].astype(float) 122 | df['CLS'] = df['CLS'].astype(float) 123 | 124 | CSV(df) 125 | 126 | ## CSV Generator 127 | 128 | def CSV(df): 129 | import datetime 130 | #spitting out a CSV 131 | filename = datetime.date.today().strftime("%d-%m-%Y")+ 'all_scores.csv' 132 | df.to_csv(filename) 133 | 134 | print(df) 135 | print('File was saved in ' , filename) 136 | 137 | 138 | webcorevitals(url_list, device, category, today) 139 | 140 | 141 | --------------------------------------------------------------------------------