• March 3, 2024

Python Seo Project

7 Example Projects to Get Started with Python for SEO

7 Example Projects to Get Started with Python for SEO

After starting to learn Python late last year, I’ve found myself putting into practice what I’ve been learning more and more for my daily tasks as an SEO ranges from fairly simple tasks such as comparing how things such as word count or status codes have changed over time, to analysis pieces including internal linking and log file addition, Python has been really helpful:For working with large data files that would usually crash Excel and require complex analysis to extract any meaningful Python Can Help With Technical SEOPython empowers SEO professionals in a number of ways due to its ability to automate repetitive, low-level tasks that typically take a lot of time to means we have more time (and energy) to spend on important strategic work and optimization efforts that cannot be also enables us to work more efficiently with large amounts of data in order to make more data-driven decisions, which can in turn provide valuable returns on our work, and our clients’ vertisementContinue Reading BelowIn fact, a study from McKinsey Global Institute found that data-driven organizations were 23 times more likely to acquire customers and six times as likely to retain those ’s also really helpful for backing up any ideas or strategies you have because you can quantify it with the data that you have and make decisions based on that, while also having more leverage power when trying to get things Python to Your SEO WorkflowThe best way to add Python into your workflow is to:Think about what can be automated, especially when performing tedious entify any gaps in the analysis work you are performing, or have completed. I have found that another useful way to get started learning is to use the data you already have access to, and extract valuable insights from it using is how I have learned most of the things I will be sharing in this vertisementContinue Reading BelowLearning Python isn’t necessary in order to become a good SEO pro, but if you’re interested in finding more about how it can help get ready to jump You Need to Get StartedIn order to get the best results from this article there are a few things you will need:Some data from a website (e. g., a crawl of your website, Google Analytics, or Google Search Console data) IDE (Integrated Development Environment) to run code on, for getting started I would recommend Google Colab or Jupyter open mind. This is perhaps the most important thing, don’t be afraid to break something or make mistakes, finding the cause of an issue and ways to fix it is a big part of what we do as SEO professionals, so applying this same mentality to learning Python is helpful to take any pressure off. 1. Trying Out LibrariesA great place to get started is to try out some of the many libraries which are available to use in are a lot of libraries to explore, but three that I find most useful for SEO related tasks are Pandas, Requests, and Beautiful ndasPandas is a Python library used for working with table data, it allows for high-level data manipulation where the key data structure is a Frames are essentially Pandas’ version of an Excel spreadsheet, however, it is not limited to Excel’s row and byte limits and also much faster and therefore efficient compared to best way to get started with Pandas is to take a simple CSV of data, for example, a crawl of your website, and save this within Python as a you have this store you’ll be able to perform a number of different analysis tasks, including aggregating, pivoting, and cleaning vertisementContinue Reading Belowimport pandas as pd
df = ad_csv(“/file_name/and_path”)
df. headRequestsThe next library is called Requests, which is used to make HTTP requests in uses different request methods such as GET and POST to make a request, with the results being stored in example of this in action is a simple GET request of URL, this will print out the status code of a page, which can then be used to create a simple decision-making requests
#Print HTTP response from page
response = (”)
#Create decision making function
if atus_code == 200:
print(‘Success! ‘)
elif atus_code == 404:
print(‘Not Found. ‘)You can also use different requests, such as headers, which displays useful information about the page such as the content type and a time limit on how long it took to cache the response. #Print page header response
headers = response. headers
#Extract item from header response
response. headers[‘Content-Type’]There is also the ability to simulate a specific user agent, such as Googlebot, in order to extract the response this specific bot will see when crawling the vertisementContinue Reading Belowheaders = {‘User-Agent’: ‘Mozilla/5. 0 (compatible; Googlebot/2. 1; +)’}
ua_response = (”, headers=headers)
Beautiful SoupThe final library is called Beautiful Soup, which is used to extract data from HTML and XML ’s most often used for web scraping as it can transform an HTML document into different Python example, you can take a URL and using Beautiful Soup, together with the Requests library, extract the title of the page. #Beautiful Soup
from bs4 import BeautifulSoup
import requests
#Request URL to extract elements from
url= ”
req = (url)
soup = BeautifulSoup(, “”)
#Print title from webpage
title =
Additionally, Beautiful Soup enables you to extract other elements from a page such as all a href links that are found on the link in nd_all(‘a’):
2. Segmenting PagesThe first task involves segmenting a website’s pages, which is essentially grouping pages together in categories dependent on their URL structure or page vertisementContinue Reading BelowStart by using simple regex to break the site up into different segments based on their URL:segment_definitions = [
[(r’\/blog\/’), ‘Blog’],
[(r’\/technical-seo-library\/’), ‘Technical SEO Library’],
[(r’\/hangout-library\/’), ‘Hangout Library’],
[(r’\/guides\/’), ‘Guides’], ]
Next, we add a small function that will loop through the list of URLs and assign each URL with a category, before adding these segments to a new column within the DataFrame which contains the original URL e_segment_definitions = True
def segment(url):
if use_segment_definitions == True:
for segment_definition in segment_definitions:
if ndall(segment_definition[0], url):
return segment_definition[1]
return ‘Other’
df[‘segment’] = df[‘url’](lambda x: get_segment(x))
There is also a way to segment pages without having to manually create the segments, using the URL structure. This will grab the folder that is contained after the main domain in order to categorize each vertisementContinue Reading BelowAgain, this will add a new column to our DataFrame with the segment that was get_segment(url):
slug = (r’? :\/\/. *? \//? ([^\/]*)\/’, url)
if slug:
return (1)
return ‘None’
# Add a segment column, and make into a category
3. Redirect RelevancyThis task is something I would have never thought about doing if I wasn’t aware of what was possible using llowing a migration, when redirects were put in place, we wanted to find out if the redirect mapping was accurate by reviewing if the category and depth of each page had changed or remained the vertisementContinue Reading BelowThis involved taking a pre and post-migration crawl of the site and segmenting each page based on their URL structure, as mentioned llowing this I used some simple comparison operators, which are built into Python, to determine if the category and depth for each URL had [‘category_match’] = df[‘old_category’] == (df[‘redirected_category’])
df[‘segment_match’] = df[‘old_segment’] == (df[‘redirected_segment’])
df[‘depth_match’] = df[‘old_count’] == (df[‘redirected_count’])
df[‘depth_difference’] = df[‘old_count’] – (df[‘redirected_count’])
As this is essentially an automated script, it will run through each URL to determine if the category or depth has changed and output the results as a new new DataFrame will include additional columns displaying True if they match, or False if they don’ just like in Excel, the Pandas library enables you to pivot data based on an index from the original vertisementContinue Reading BelowFor example, to get a count of how many URLs had matching categories following the analysis will enable you to review the redirect rules that have been set and identify if there are any categories with a big difference pre and post-migration which might need further investigation. 4. Internal Link AnalysisAnalyzing internal links is important to identify which sections of the site are linked to the most, as well as discover opportunities to improve internal linking across a vertisementContinue Reading BelowIn order to perform this analysis, we only need some columns of data from a web crawl, for example, any metric displaying links in and links out between, we want to segment this data in order to determine the different categories of a website and analyze the linking between ternal_linking_pivot[‘followed_links_in_count’] = (internal_linking_pivot[‘followed_links_in_count’])(‘{:. 1f}’)
internal_linking_pivot[‘links_in_count’] = (internal_linking_pivot2[‘links_in_count’])(‘{:. 1f}’)
internal_linking_pivot[‘links_out_count’] = (internal_linking_pivot[‘links_out_count’])(‘{:. 1f}’)
Pivot tables are really useful for this analysis, as we can pivot on the category in order to calculate the total number of internal links for vertisementContinue Reading BelowPython also allows us to perform mathematical functions in order to get a count, sum, or mean of any numerical data we have. 5. Log File AnalysisAnother important analysis piece is related to log files, and the data we are able to collect for these in a number of different useful insights you can extract include identifying which areas of a site are crawled the most by Googlebot and monitoring any changes to the number of requests over addition, they can also be used to see how many non-indexable or broken pages are still receiving bot hits in order to address any potential issues with crawl, the easiest way to perform this analysis is to segment the URLs based on the category they sit under and use pivot tables to generate a count, or average, for each vertisementContinue Reading BelowIf you are able to access historic log file data, there is also the possibility to monitor how Google’s visits to your website have changed over are also great visualization libraries available within Python, such as Matplotlib and Seaborn, which allow you to create bar charts or line graphs to plot the raw data into easy to follow charts displaying comparisons or trends over time. 6. Merging DataWith the Pandas library, there is also the ability to combine DataFrames based on a shared column, for example, vertisementContinue Reading BelowSome examples of useful merges for SEO purposes include combining data from a web crawl with conversion data that is collected within Google will take each URL to match upon and display the data from both sources within one rging data in this way helps to provide more insights into top-performing pages, while also identifying pages that are not performing as well as you are vertisementContinue Reading BelowMerge TypesThere are a couple of different ways to merge data in Python, the default is an inner merge where the merge will occur on values that exist in both the left and right ever, you can also perform an outer merge which will return all the rows from the left DataFrame, and all rows from the right DataFrame and match them where vertisementContinue Reading BelowAs well as a right merge, or left merge which will merge all matching rows and keep those that don’t match if they are present in either the right or left merge respectively. 7. Google TrendsThere is also a great library available called PyTrends, which essentially allows you to collect Google Trends data at scale with are several API methods available to extract different types of example is to track search interest over-time for up to 5 keywords at once. Another useful method is to return related queries for a certain topic, this will display a Google Trends score between 0-100, as well as a percentage showing how much interest the keyword has increased over vertisementContinue Reading BelowThis data can be easily added to a Google Sheet document in order to display within a Google Data Studio ConclusionThese projects have helped me to save a lot of time on manual analysis work, while also allowing me to discover even more insights from all of the data that I have access to. I hope this has given you some inspiration for SEO projects you can get started with to kickstart your Python vertisementContinue Reading BelowI’d love to hear how you get on if you decide to try any of these and I’ve included all of the above projects within this Github Resources:How to Predict Content Success with PythonAn Introduction to Natural Language Processing with Python for SEOsAdvanced Technical SEO: A Complete GuideImage CreditsAll screenshots taken by author, December 2020
Using Python scripts to analyse SEO and broken links on your ...

Using Python scripts to analyse SEO and broken links on your …

Notice: While JavaScript is not essential for this website, your interaction with the content will be limited. Please turn JavaScript on for the full experience.
Python is all about automating repetitive tasks, leaving more time for your other Search Engine Optimization (SEO) efforts. Not many SEOs use Python for their problem-solving, even though it could save you a lot of time and effort. Python, for example, can be used for the following tasks:
Data extraction
Analysis & visualization
Machine learning
Deep learning
We’ll be focussing mostly on data extraction and analysis in this article. The required modules will be indicated for each script.
Python SEO analyzer
A really useful script for analyzing your website is called ‘SEO analyzer’. It’s an all round website crawler that analyses the following information:
Word count
Page Title
Meta Description
Keywords on-page
Missing title
Missing description
Missing image alt-text
This is great for a quick analysis of your basic SEO problems. As page title, meta descriptions and on-page keywords are important ranking factors, this script is perfect for gaining a clear picture of any problems that might be in play.
Using the SEO analyzer
After having installed the necessary modules (BeautifulSoup 4 + urllib2) for this script and having updated your Python to version 3. 4+, you are technically ready to use this script. Json or working variants, however, can be useful for exporting the data you gain from the SEO analyser. After having installed the script, these are the commands you can use:
seoanalyze seoanalyze –sitemap As seen in the examples above, for both
telefoonvergelijk, it’s possible to either crawl the website, or the XML sitemap of a website in order to do an SEO analysis. Another option is to generate HTML output from the analysis instead of using json. This can be done through the following command:
seoanalyze –output-format-html
If you have installed json and want to export the data, use the following command:
from seoanalyzer import analyse
output = analyse(site, sitemap)
You can also choose for an alternative path, running the analysis as a script, as seen in the example below:
This will export the file into a html after having run the –output-format html script.
This seoanalyze script is great for optimizing your page titles, meta descriptions, images and on-page keywords. It’s also a lot faster than Screaming Frog, so if you’re only looking for this information, running the seoanalyze script is more efficient.
Link status analyser
Another way to use Python for Search Engine Optimization is by using a script that crawls your website and analyses your URL status codes. This script is called Pylinkvalidator and can be found here). All it requires is BeautifulSoup if you’re running it with Python 3. x. If you’re running a 2. x version like 2. 6 or 2. 7, you should not need BeautifulSoup.
In order to speed up the crawling, however, it might be useful to install the following libraries:
1) lxml – Speeds up the crawling of HTML pages (requires C libraries)
1) gevent – enables pylinkvalidator to use green threads
1) cchardet – Speeds up document encoding detection
Do keep this in mind, they could be very useful for crawling larger websites, and just to enhance the link status analyser.
What this script essentially does, is crawl the entire URL structure of a website in order to analyse the status codes of each and every URL. This makes it a very long process for bigger websites, hence the recommendation of using the optional libraries to speed this up.
Using the link status analyser
Pylinkvalidator has a ton of different usage options for usage. For example, you can:
Show progress
Crawl the website and pages belonging to another host
Only crawl a single page and the pages it links to
Only crawl links, ignore others (images, stylesheets, etc. )
Crawl a website with more threads or processes than default
Change your user agent
Crawl multiple websites
Crawling body tags and paragraph tags
Showing progress through -P or –progress is recommended, as without it, you will find yourself wondering when your crawl will be done without any visual signs. The command for crawling more threads (– workers=’number of workers’) and processes (– mode=process –workers=’number of workers’) can be very useful as well.
Of course, the script has many more options to explore. The examples below show some of the possible uses:
-p The function above crawls the website and shows progress.
-p workers=4 This function crawls a website with multiple threads and shows progress.
-p –parser=lxml This function uses the lxml library in order to speed up the crawl while showing progress.
-P –types=a The function above only crawls links () on your website, ignoring images, scripts, stylesheets and any other non-link attribute on your website. This is also a useful function when crawling the URLs of large websites.
After the script has run its course, you’ll get a list of URLs with status codes 4xx and 5xx that have been found by crawling your website. Along with that, you’ll gain a list of URLs that link to that page, so you’ll have an easier time fixing the broken links. The regular crawl does not show any 3xx status codes. For more detailed information about what URLs your pages can be reached from, try the following function:
–report-type=all This give information about the status code of a page, and all the other pages that link to a page.
An incredibly useful SEO tool you can use to crawl your website for broken links (404) and server errors. Both of these errors can be bad for your SEO efforts, so be sure to regularly crawl your own website in order to fix these errors ASAP.
While these scripts are incredibly useful, there are a lot of various uses for Python in the world of SEO. Challenge yourself to create scripts that make your SEO efforts more efficient. There are plenty of Python scripts to make your life easier. There’s scripts for checking your hreflang tags, canonicals, and much more. Because who, in today’s day and age, still does stuff manually when it can be automated?
19 Python SEO projects that will improve your site - Practical ...

19 Python SEO projects that will improve your site – Practical …

Although I have never really considered myself a technical SEO, I do need to do quite a bit of SEO work as part of
my role as an Ecommerce Director. Unsurprisingly, like many others, I’m now using Python for the very vast majority
of the work I undertake in this field.
Using Python for SEO makes a lot of sense. Many processes can be automated, saving you loads of time. There are
Python tools for almost everything, from web scraping, to machine learning, and it’s easy to integrate data from
multiple sources using tools such as Pandas.
Here are a few of the Python SEO projects I’ve undertaken for my sites, and at work, to give you some inspiration on
how you can apply it to SEO. If you’re new to Python, I think these show why it’s worth taking the time to learn!
1. Automatically generate meta descriptions using AI
There have been some mind-blowing improvements in the performance of Natural Language Generation models in recent years, largely thanks to the development of so-called “transformer” models. These are pre-trained on massive datasets and can then be fine-tuned to perform other tasks, such as text summarisation.
I recently used this approach to generate surprisingly high-quality short descriptions for ecommerce product pages, but the same technique could easily be applied to the creation of meta descriptions, if you’re faced with a task too large or inefficient for humans to handle. It works well, but you’ll likely need a human editor to make fine adjustments.
How to auto-generate product summaries using deep learning
2. Identify SEO keywords
While there are loads of excellent keyword generator tools available commercially, they’re also relatively simple to create yourself. Two excellent sources of the data to power these are the suggested keywords from Google Autocomplete and the questions from the People Also Ask section of the Google SERPs.
You can use Python to create simple tools that all you to bulk generate and extract both suggested keywords (ranked by relevance) and give you a list of all the questions people also ask about your topic of choice, giving you a whole plethora of potential keywords to include in your content.
How to identify SEO keywords using Google Autocomplete
How to scrape People Also Ask data using Python
3. Optimise your content for Extractive Question Answering
SEO has now moved far beyond just the inclusion and density of keywords on your page, and Google is using sophisticated Natural Language Understanding models, such as BERT, to read and understand your content to answer any questions searchers may have.
I recently used the BERT model for Extractive Question Answering (or EQA) to assess how well my content worked for answering certain questions. My theory is, if I can write the content so my more simplistic BERT model can find the answers adequately, then Google should have no problems and the content should rank higher. Here’s how I did it.
How to assess product copy using EQA models
4. Identify near-duplicate content
One common issue I encounter in my job running ecommerce websites is that writers often copy and paste content from suppliers without rewriting it. Worse still, they’ll also share the same content over multiple pages on the same site, which results in widespread “near-duplicate” content.
This can be a bit tricky to identify, but I’ve gained good results using an algorithm called Longest Matching Subsequence (LMS), which returns the length of the longest string found in two pieces of content. It’s a great way to identify which content needs to be rewritten to avoid duplicate content harming rankings.
How to identify near-duplicate content using LMS
5. Identify keyword cannibalisation
Another really common issue, especially on larger sites, is that content has often been optimised for or ranks for the same keywords. Given that Google (usually) limits the number of times a site can appear for the same phrase within the results, it pays to mix things up a bit.
You can use Python, Pandas, and the Google Search Console API to extract data on the keywords each URL is ranking for, and then identify the amount of keyword cannibalisation across pages to help reduce this by making adjustments to the content. Here’s how it’s done.
How to identify keyword cannibalisation using Python
6. Analyse non-ranking pages and index bloat
Google Search Console data is a rich source of information on potential site issues, and checking it can help identify various ways you can improve your search engine rankings.
One useful analysis to undertake is to identify your non-ranking pages, so you can go back and improve internal linking, add them to the index if they’re missing, or try to determine why they may have been excluded. Similarly, index bloat (too many pages in the index) is also a bad thing in some cases and can also be analysed easily using Python.
How to analyse non-ranking pages and search index bloat
7. Identify search traffic trends
If you’re looking for those keywords which are going to be the next big thing in your market, then Google Trends is worth using. There’s no official Google API for Google Trends, but it’s possible to extract the data using Python and analyse it in Pandas (or Excel if that’s your bag – I won’t judge).
How to analyse search traffic using the Google Trends API
8. Bulk audit a site’s Core Web Vitals
Core Web Vitals are a bunch of site performance metrics that examine how quickly your site loads and renders on various devices, and how well it’s set up from an SEO perspective. These are soon to become a ranking factor for Google (albeit probably a fairly minor one).
You can examine Core Web Vitals in Chrome using the Lighthouse tool that’s built-in. However, it’s worth using Python and the Core Web Vitals API to perform these checks in bulk, allowing you to simultaneously check multiple pages and multiple sites in just a few seconds.
How to audit a site’s Core Web Vitals using Python
9. Identify internal and external links
Internal linking remains an important factor in SEO, and also helps reduce bounce rate and improve the user experience. Python makes it relatively straightforward to create web scraping tools that let you examine where internal and external links are present, so you can improve internal linking.
How to identify internal and external links using Python
10. Access Google Analytics and Google Search Console data
If you’re an SEO, you’ll likely spend a lot of your time using Google Analytics and Google Search Console data. You’ll be pleased to know that you can access both data sources computationally in Python using the official APIs.
These are a bit fiddly to use and require lots of code, however, I’ve written a couple of handy Python packages –
GAPandas and EcommerceTools – that make the process much easier and require very little code. You can even blend
data from the two sources together and do sophisticated SEO testing in just a few lines of code. They both integrate with
Pandas too.
How to use EcommerceTools for technical SEO
How to use GAPandas to view your Google Analytics data
How to access the Google Search Console API using Python
How to join Google Analytics and Google Search Console data
How to compare time periods using the Google Search Console API
How to run time-based SEO tests using Python
11. Crawl a site for 404 errors and 301 redirect chains
While there are loads of off-the-shelf commercial SEO tools that do the same thing, it’s fairly easy to create a Python script to scan your sites for 404 errors and 301 redirect chains, both of which will harm your rankings and the user experience. Here’s how to do it.
How to scan a site for 404 errors and 301 redirect chains
12. Detect anomalies in Google Search Console data
Python has some superb anomaly detection modeling packages available. These can be applied to pretty much any kind of time series data and are great for automating the process or poring over data to look for potential issues.
I’ve previously covered how to create anomaly detection models that can be used on both Google Analytics and Google Search Console data. These work well, but do require some prior knowledge of machine learning, so are the more sophisticated end of Python SEO.
How to detect Google Search Console anomalies
How to create ecommerce anomaly detection models
13. Generate automated PDF reports
If reporting is a big part of your job, then you’ll likely benefit from automating, or semi-automating, some of this work to free up your time to focus on more interesting tasks. I’ve create a couple of Python packages to do this.
GAPandas can be used to automate reports from Google Analytics. EcommerceTools lets you do the same with Google Search Console data, while Gilfoyle turns the Pandas dataframes of data into attractive PDF reports. They can all be set up to run automatically, so you can put your feet up.
How to create PDF reports in Python using Pandas and Gilfoyle
How to create monthly Google Analytics reports in Pandas
14. Machine translate your content
If you run multilingual sites, or want to test what would happen if you did, then machine translation is worth considering. While arguably not as good as a human, the results are often surprisingly good. Python makes it easy to do this in bulk, and for free.
How to machine translate product descriptions
15. Build a web site scraper
Most SEOs who use Python use it for web scraping in some form. There are some absolutely amazing web scraping packages available for Python (check out Scrapy, Requests-HTML, and Advertools). These vary in complexity, and you’ll benefit from some HTML and CSS knowledge, but you can use them for pretty much anything. Here are some examples.
How to build a web scraper using Requests-HTML
How to scrape a site’s page titles and meta descriptions
16. Scrape and OpenGraph metadata
Rather than just scraping HTML, it’s also worth scraping metadata. Site owners often add or OpenGraph metadata to their sites to help search engines find structured content and this can usually be extracted using more sophisticated web scraping tools, such as Extruct.
How to scrape metadata using Python
How to use Extruct to identify metadata usage
How to scrape Open Graph protocol data using Python
17. Scrape and analyse XML sitemaps
XML sitemaps have many uses for SEOs, and in web scraping projects. They can be scraped to give you the initial list of pages to scrape, and they can be analysed to identify the spread of keywords or other factors on your site, or those of your competitors. Here’s how you can access them using Python.
How to parse XML sitemaps using Python
How to parse URL structures using Python
18. Analyse files
Similarly, the found on the root of pretty much every website can tell you a lot about the site structure, and reveal the location of any sitemaps. These can be scraped using Python and parsed in Pandas allowing you to see how a site is configured.
How to scrape and parse a file using Python
19. Scrape Google search results
While it’s not strictly permitted, pretty much every SEO likely uses content that’s been scraped from Google in some
shape or form. Since Google doesn’t really permit this, it can be a cat and mouse game since the obfuscated code in
the page requires constant updating to ensure scrapers continue to work. Here are a few ways you can utilise this
powerful Python SEO technique. If you want to get fancy you can even try things like search intent classification.
How to scrape Google results in three lines of Python code
How to scrape Google search results using Python
How to count indexed pages using Python
How to access the Google Knowledge Graph Search API
Matt Clarke, Saturday, May 22, 2021

Frequently Asked Questions about python seo project

Can Python be used for SEO?

Python, one of the most sophisticated programming languages can drastically improve the quality of your SEO. By abandoning Excel and the use of spreadsheets you can use it to automate the implementation process of machine learning algorithms and leveraging APIs.May 12, 2021

What is Python for SEO?

Python is all about automating repetitive tasks, leaving more time for your other Search Engine Optimization (SEO) efforts. Not many SEOs use Python for their problem-solving, even though it could save you a lot of time and effort. Python, for example, can be used for the following tasks: Data extraction.

How do I start a SEO project?

How to Start an SEO CampaignStep 1: Set KPIs & Goals. … Step 2: Analyze Your Current Website Setup. … Step 3: Topic Creation & Keyword Research. … Step 4: Establish a Pillar Content Strategy. … Step 5: Perform an SEO Audit. … Step 6: Work on Audit Findings. … Step 7: Work on Local SEO. … Step 8: Work on Back Links.Mar 12, 2018

Leave a Reply

Your email address will not be published. Required fields are marked *