Setting Up Search Engine Marketing Campaigns on a Large Scale


Starting and managing SEM accounts can be —and usually is —a daunting task. In addition to hitting your business goals (revenue, conversions, clicks, etc.), you need an account structure that is not only systematic but easy to understand and maintain.

In this article, I first briefly share my thoughts on account structure, then follow with detailed techniques that can help you build large accounts with numerous products — and in a flexible way.

In discussing account structure, I share what I think are the most important elements of SEM accounts, and how they can best be matched. It is not an explanation of what these elements are, as I am sure you know that already. Rather, it is to make explicit my assumptions and views, so it is clear why I am doing what I am doing.

SEM Account Structure: Keywords >> Ads >> Landing Pages 

The main process of using search engines has not changed much; you go to the search engine’s page, type (or speak) some words, view results, then click on your page of choice. 

Based on this, the three most important elements in building an account are: 

  1. Keywords: Representing the intention of the user, and what they want. 
  2. Ads: Your promise to the user that you will satisfy their need, as in, “I hear you, I have what you want, this is how I can help you, please visit this page.”
  3. Landing pages: This is where you fulfill the promise that you made to the user. 

If you properly map keywords to ads and send users to the right landing pages, you have achieved the core part of setting up your SEM campaigns. As it so happens, this approach is in line with the main elements that determine quality score: expected CTR, ad relevance, and landing page experience.

And while there are many other important things to consider, such as ad extensions, bidding, and campaign settings, they require far less time to create or set up.

In practical terms, the essential part of setting up campaigns entails creating two tables, one for the keywords and the other for the ads; this is what we will be doing using a fictional account. 

I will be using the programming language Python with a few functions that I have developed. I encourage you to follow along on the interactive version of this article, where you can make modifications to the code and see how that changes the results. Most of the coding is quite simple, and you should be able to play with it even if you have no prior programming knowledge. 

Generating Relevant Keywords

Deconstructing the keyword research process, here is how we arrive at our final list of keywords.

First, go to a keyword tool and enter a few keywords that are clearly relevant to the product/service you are promoting. The tool then gives you a few hundred similar keywords. After that, sort through them and select those that you believe are most relevant.

Once you are done with selecting the keywords — export, format, and upload them. Then repeat the process for every product/service that you have. For instance, assume we are doing keyword research to create a digital marketing campaign for a used car website.

Using this example, I will go through the process of selecting relevant keywords.

Let’s start with the product “Honda”. We would likely enter something like “buy honda”, “honda price”, or “honda for sale” to generate the keyword tool’s suggestions.

While considering the keywords, keep in mind that there are two conditions a given keyword needs for it to qualify as relevant: 

  1. Product: It has to contain the product (“honda” or a synonym, in this example).
  2. Word: It has to contain a verb or word that indicates an intention (e.g., “buying a honda”).

Now, if you think of the possible verbs/words that can express that intention, you will find that they are not that many. Let’s brainstorm some: buy, price, shop, used, second hand, auto loan, car loan, auto finance, car finance, cheap, cheapest, best price, lease, leasing, certified.

I am sure you can think of others, but the idea is that while there is an infinite number of combinations of words and variations, the words themselves are few. Of course, using phrase match and modified broad match is crucial in allowing users to come up with combinations that we failed to consider.

The important thing is that we filter out irrelevant keywords by making sure that the proper verb is there along with the product name. Needless to say, the proper negative match keywords should also be added to ensure relevancy.

Next, we will manually construct our first ad group using just the first two words as a demonstration. The way I do this is to simply concatenate “honda” with each of the words, once before and once after: 

buy honda
honda buy
price honda
honda price
used honda
honda used

Coupled with phrase match, you can be confident that you have covered the majority of keywords that contain “honda” with any of those three verbs/words (buy, price, used). Furthermore, “buy honda in <location>”, “best site to buy honda”, etc., would also be included. The corner case is when a user has inserted a word between the word and the product, such as “buy 2015 model honda”; this can be accounted for with a modified broad match.

Assuming we are happy with the list of keywords that we produced using three match types — exact, phrase, and modified broad — it is easy to do the same for the specific honda models (e.g., “honda accord”, “honda civic”, etc.) that you have on your website.

Now, our next task in generating keywords entails two steps: 

  1. Match the products with their corresponding URLs: this is a simple matter, as your colleague or client can easily send you a list of all the products they sell, with their corresponding landing pages.
  2. Generate a list of verbs/words that signal the intention we are trying to satisfy.

Clearly, step two is the critical one. Using your keyword tool, you can come up with the verb/word combinations to populate your intention list, and repeat the process for specific car makes or models. Then you can brainstorm until you are satisfied that your list of verbs/words is complete.

Now that you are done with generating keywords, the next step is coding to arrive at the final result.

Building Large Accounts: Coding

The challenge here is to repeat the keyword generation process for a large number of products. To do this, we first put the keywords in the proper format, the table that contains the campaign name, ad group name, keyword, and match type, so we can then upload it.

In advertools a Python package for online marketing the kw_generate function is the one we will use for this task. Here are the main arguments that the function takes:

  • products: Self-explanatory. In our used cars example, that would be ‘honda’, ‘honda accord’, ‘toyota’, etc.
  • words: The verbs/words that we finalized.
  • match_types: A list of up to four possible match types; Exact, Phrase, Modified, or Broad.
  • order_matters: True or False. Whether or not the order of the words in the keyword matters. If True, then you will have “honda price” as well as “price honda”, otherwise you will be limited to “honda price”. 
  • max_len: The maximum number of words in a keyword that you want. For example, if you specify three, the function will combine “honda” with one word, as well as with two words, so you end up with keywords consisting of two and three words, such as “honda buy”, “honda price”, and “honda buy price”, “honda price buy”, and so on. This preempts the different combinations that will eventually come up and improves your coverage. It also exponentially adds to the number of keywords you are generating. More than three is possible, but it becomes way too complicated and cumbersome to be useful. With two and three words per keyword, you should get very good coverage. 
  • campaign_name: Whatever you want to name your campaign. The default is ‘SEM_Campaign’.

Let’s see how it works with one product and two words:

Generate keywords (max_len=2)

As you can see above, all you need to think about are the words, which makes supplying the function parameters very easy. With one line of code, you get the final table, ready for uploading and launching your keywords.

Note that each product will get its own ad group, and ad group names are capitalized for better readability. Each keyword is repeated according to how many match types you specify, which also serves to generate labels for your keywords.

The labels are the words in each keyword minus the product. In this example, they are “Buy”, “Price” and the product, “honda”, is excluded.

Now you can easily filter all the “price” keywords and compare them with the “buy” keywords. This will include all products that contain them: ‘toyota price’, ‘bmw price’ and so on. This gives you another dimension to use in analyzing performance.

In the above example, we ended up with six keywords in total. Now let’s run the same function by specifying max_len as three words:

Generate keywords (max_len=3)Generate keywords (max_len=3)

Now we have nine keywords because we are combining words together. Let’s see what happens if we do the same but specify order_matters as True: 

Generate keywords (order_matters=True)Generate keywords (order_matters=True)

We generate thirty (I’m just showing the first and last five rows). Note that the labels where keywords consisting of multiple words (e.g., price honda buy) also have more than one word in them (e.g., Price;Buy).

Building Large Accounts: Numerous Products

Now let’s flesh out the full account.

We first create the variable car_words that includes the words we came up with:

Word list (car_words)Word list (car_words)

This renders a random list of some popular car makes and models, which I will use for exemplary purposes:

Car makes and models list with URLsCar makes and models list with URLs

Matching the product names with their corresponding URLs is crucial because when we create the ads, we will be using the same product names for ad groups to ensure they are consistent with each other.

To illustrate, I constructed these fake URLs with a random set of car makes and models:

Generate car keywords (max_len=2)Generate car keywords (max_len=2)

Generate car keywords (max_len=3)Generate car keywords (max_len=3)

And we are done. The above are two samples of fifteen random rows each. The first table has 6,300 rows (keywords), and the second has 138,600. The only difference is that I specified max_len as two in the first and three in the second.

Ad group & keyword summariesAd group & keyword summaries

The summaries above show the number of keywords that we have for each match type under each ad group, using the first three ad groups as a sample. Another important effect of this approach is consistency. All ad groups have the exact same set of keywords, with the only difference of having the product name substituted. This consistency should make it easier to compare ad groups.

It takes the same amount of work to generate six keywords as well as 6,300 in this case, or by changing a number, we get 138,600.

When specifying max_len=3, we get some keywords that are more specific, and convey a stronger intent to buy, like “second hand honda price” or “buy used honda”. Some of these additional keywords are not particularly relevant (such as “car loan car finance toyota”), but it wouldn’t hurt to have them in your account as it is easy to remove them, especially that now we have labels. For instance, you can filter out rows where the label is “Car Loan;Car Finance”. You can look at one ad group as a sample and identify the cases where this doesn’t make much sense, and then apply it to the whole table. 

Now, perhaps you want to target more generic car terms that have a high volume but lower likelihood of converting. I am referring to product names like car, auto, autos, etc.

We again use the same approach for generating keywords. The words have already been defined, so now we just have to think of a few ways of saying “car”. 

Generic car keywordsGeneric car keywords

Your website might have other ways of grouping cars. For example, you might have a section for SUVs, or maybe electric cars, hybrid cars, Japanese cars, and so on. 

Again, you simply have to come up with two lists: one for the products (variations of “SUV” for example) and one for the words, and you can do it in one step. You also can easily generate more specific keywords, such as BMW 320d, BMW 330d, bmw325xi, BMW 325i.

To demonstrate with another example, let’s generate travel keywords for the top destinations in the world. The following code retrieves the top destinations from Wikipedia and creates the variable called cities from the third column:

Wikipedia top cities listWikipedia top cities list

Now that we have our products list ready, we just need to think of verbs that convey an intention to travel. Let’s call them travel_words:

Generate travel keywordsGenerate travel keywords

As the table above shows, we generated 57,540 keywords for the destinations as well as a random subset of the keywords.

And as a final example, let’s create keywords for a recipes website. The following code extracts the national dish for each country from Wikipedia:

Import national dishes from WikipediaImport national dishes from Wikipedia

 Now we do the same as before to generate recipes keywords: 

Generate recipes keywordsGenerate recipes keywords

You’re Invited!

I am sure you can see a pattern here. For each industry, there can be a fairly standardized set of words that work with that vertical. So why not prepare a set of keywords for different industries, and in different languages, to make it easy for people to start campaigns?

I created a sheet that is downloadable and editable, which you can explore and make any changes you think are useful, so everyone can benefit from the ideas shared.

Starter words for different industriesStarter words for different industries

Limitations and Possible Issues: 

  1. Multiple match types in one ad group: I have never understood why this is a bad thing, and I usually put different match types in the same ad group because I find it to be more manageable and streamlined. If you like this approach, you can simply concatenate the ad group name with the match type, and end up with ‘Toyota – Phrase’ and ‘Toyota – Exact’; this will create those new ad groups for you. You need to make sure your change is consistent with the ads table.
  2. All in one campaign: If you prefer to have more control over budgets and targeting, you may want to place each product in its own campaign (which I think is a good idea). All you have to do is duplicate the ad group column, and this will create them as campaigns. Combined with the previous step, you can end up with a campaign for Toyota and ad groups for each of the match types that you are using. Again, you will want to make sure your changes are consistent with the ads table if you want to make these campaign structure changes.
  3. Synonyms and spelling variations: There is no straightforward solution for this issue. For example, If you have a travel campaign, all of the following product names might be used to indicate the same destination: London, LHR, LGW, LDN, UK, England. Or maybe you have a real estate site: 2 bedroom, two bedroom, 2br, 2bed might all be used for the same purpose. In some cases like travel, it might be easier to come up with state, city, country, and airport codes to get synonyms, and in other cases, you will have to be creative. 
  4. Brand and sub-brand issues: In our example, we used “toyota camry” and “ford mustang”. But why not just use ‘camry’ as a product and create the keyword ‘buy camry’? The problem is with model names like Dodge Charger for instance. If you have the keyword ‘buy charger’ and not ‘buy dodge charger’, your budget is going to be vanishing sooner than you want, and you will even be penalized for being irrelevant. A possible solution might be to include the model without the make only for the names that are clearly referring to the car model and not something else. 
  5. Generic word products: In some cases like movie titles, it’s not enough to have the movie name on its own. One of the movies released a few years ago was titled “Sing”, so the keywords ‘watch sing’ or ‘download sing’ won’t mean much. So in these types of keywords, you will need to add a qualifier like ‘the film’ or ‘the movie’, to make it clear what you are targeting. 
  6. Negatives: This is not an issue actually, and it is very easy to generate, especially that we have a set of uniform and consistent ad groups. For used cars it would be “new”, “2019”, “2020”, “brand new”, etc. In some cases, you will probably need to add specific negatives at the ad group level. For example, there is London, UK, and London, Ontario in Canada. You will need to add -Canada as a negative keyword if you are targeting the London of the UK and vice versa.
  7. Other issues: There must be some issues that I haven’t thought of, and I am hoping that you share them if you disagree with the approach, or if you have suggestions as to what might go wrong. 

To summarize the discussion on keywords, since getting product names and their URLs is trivial in most cases, your job boils down to creating a few words to combine them with. I am sure if asked to come up with twenty words for learning courses, or booking a hotel, or buying a certain product, that you can easily do it in a few minutes. The discussion is now about those 20 – 30 words that make sense for you, and then you are basically done.

With this approach, you are making a transition from keyword research to keyword “manufacturing”!

Now let’s manufacture some ads. 

Creating Ads

I would like to discuss two main techniques for creating ads on a large scale:

1. Constructing ads (bottom-up approach): Nothing really different or new here, and can mostly be done with any spreadsheet software. There are some minor benefits though. 
2. Splitting text to get ads (top-down approach): This approach capitalizes on text that might be on landing pages and provides a technique for creating ads from that text. 

Constructing Ads (bottom-up approach)

This is a simple way of creating ads. Creating each of the slots one by one, and grouping them into one table.
The function ad_create automates this by allowing you to provide the following parameters: 

  • Template: This is the text of the ad slot you are creating. It could be a header or a description line. Product names will dynamically be inserted into their proper position that you specify. For example, you can write “Get the latest {}”, and the product name will go in the empty space within the curly braces. 
  • Replacements: A list of the products that you are selling. As a result, you will get “Buy Used Honda”, “Buy Used Toyota”, “Buy Used BMW”, and so on. 
  • Fallback: In case your product name is too long and won’t fit in the maximum number of characters allowed, this should replace the long product name with a suitable generic word that might make sense. 
  •  Max_len: The maximum number of characters allowed for that slot of the ad. This makes sure that the text together with replacement (or fallback) don’t exceed a certain number.

Let’s see how it works with one ad slot.

ad_create sample usage (one ad slot)ad_create sample usage (one ad slot)

Product names are inserted where we specified. In the cases where the text would be longer than max_len (30 in this example), the fallback word “Cars” was inserted.
Now we do it to construct all the ads.

Full ads table with ad_createFull ads table with ad_create

In some ads, the name of the cars was too long for the maximum number of characters allowed, so it was replaced with “Cars”. We were able to put the car names in Description 1, as it allows for more space.
It is easy to think of variations of the ads above: changing text, different order, different call to action and so on. 

I won’t spend time about copywriting, split testing and the different ways you can communicate and capture the audience. This is a totally different subject, and extremely important, but I am mainly focusing here on techniques that enable us to build ads on a large scale. As with keywords, every set of ads can be generated with one function call, so feel free to experiment with different versions and approaches, based on your strategy and brand guidelines.

The main idea of this article is the proper mapping of keywords to relevant ads and landing pages. After generating tens of thousands of keywords and hundreds of ads, we need to make sure that the mapping is correct.

We now have two tables, one for keywords cars_kw_df3, and one for the ads ads_df; “df” is short for DataFrame. It is basically a table, and the name used in the popular data science languages. It is just a naming convention to know what your variables are, and which refers to which.

Both DataFrames have the same campaign name, so that is covered. The more important thing to make sure we got right, is to make sure that all ad groups in the keywords table exist in the ads table, and vice versa. We also need to make sure that the overlap is complete, meaning there are no ad groups in one table but not the other. Python’s set data structure is perfect for that.

Creating a set from a list of items achieves two things. First, it removes the duplicates, giving us a list of all unique elements. Second, it allows us to do operations almost exactly the same as the mathematical set operations; union, intersection, difference, etc.

The two lines below do the same thing from opposite angles. Once it checks the difference between cars_kw_df3‘s ‘Ad Group’ column with the ‘Ad Group’ column of the ads_df DataFrame and the second time it does the opposite.

Getting a result of set() means the empty set, so the mapping seems to be working. 

Verifying the correct mapping keywords > ads > landing pagesVerifying the correct mapping keywords > ads > landing pages

Creating Ads by Splitting Long Text

The other technique I would like to discuss is about utilizing the descriptive text you might have on landing pages to your advantage.

Sometimes, you might have great descriptive text that might actually be used as an ad (or part of one). This approach is becoming more relevant with Google’s launch of responsive search ads. Here, we need to provide a lot of headlines and descriptions, for the system to test different combinations. Long and detailed product descriptions are perfect for that. 

 Let’s say you have this text on your landing page (this is copied from a real page actually): 

Used 2015 BMW 5 Series 535i xDrive Sedan AWD for sale with Sport Package, Leather Seats, Driver Assistance Package, Sunroof/Moonroof, Power Package, Navigation System, Technology Package, Aluminum Wheels, Heat Package, Premium Package, Climate Package, Luxury Package, Light Package, SE Package, SL Package, Bluetooth, Backup Camera, Comfort Package, Sound Package, M Sport Package.

The text clearly contains the most important details about our product. It is also great for relevancy, to include text from the landing page, and boosts your quality score a little. It makes your ads more transparent, as this is what the user will see after clicking on the ad.

The issue is how to utilize this text when you have hundreds of descriptions like this. The challenge is to split this text into slots, each with a specified maximum number of characters, and making sure that they are meaningful words. You don’t want to have an ad “that has wo | rds that are split like this”.

We will use the ad_from_string function to achieve this. The function takes the following parameters: 

  • s (string): Any sentence/phrase that you want to split. 
  • slots: A list of numbers with the maximum allowed characters for each ad slot. The default uses Google’s text ad default (30, 30, 30, 90, 90, 15, 15), but you can change it any way you want. 
  • sep: The separator with which to split words. Typically, you don’t need to change this as text will be split by white space. Sometimes, you might have words separated by underscores or dashes. 
  • capitalize: True or False, defaults to False. If True, the final ad will have each of the words capitalized. Otherwise, the capitalization will remain unchanged from what you provide.

Let’s see how it would work with our example text. 

Usage of ad_from_string on one descriptionUsage of ad_from_string on one description

All the lengths are less than the specified lengths. You also get an additional slot at the end (length 82), and this is for the remaining text that didn’t fit in our specified slots.

You might be happy with this ad as is. You might want to use it differently. For example, you might want to have specific phrases in your headlines, and use the description lines for the details of the product. All you have to do is to run the same function with the same text, but specify the slots as (90, 90). 

Splitting description with ad_from_string int lengths of (90, 90)Splitting description with ad_from_string int lengths of (90, 90)

Obviously, this technique can be used on other ad formats, as not all Google Ads text ads have this format. You can also use them with Facebook, or Twitter ads.

The main risk here is that you might have ads, with incomplete sentences, that might not make sense. As there is no standard text that is used, you will have to check and make some modifications. In real life, data doesn’t usually come in a neat form. I scraped some sample car descriptions from the web, so we can take a look at how this might work out. These are random car descriptions, so they won’t work with our campaign because it is just a small sample for demonstration, but it works fine if you have descriptions for each of the URLs that we have.

Here is a sample of those descriptions.

Sample car descriptionsSample car descriptions

And here is one function call to split sixty sample texts to the default Google text ads format, and generate the final table: 

Generate full ads table with ad_from_stringGenerate full ads table with ad_from_string

As you can see, in some cases the splitting works perfectly, and in some others, there is a lot of blank space. The solution to these situations should not be difficult. Wherever we have an empty slot, we can fill it with one of the phrases that we used when constructing the ads with the bottom-up approach.

Let’s summarize the lengths of the descriptions that we have and see how they are distributed.
We need to see how many of our ads we have fit into one slot, two slots, and so on.

Ad lengths distributionAd lengths distribution

No description is less than thirty characters long, so we will focus on the other slots mainly. Combining the two techniques, we will check if an ad slot has text in it, in which case we will leave it as is. Otherwise, we will insert the corresponding slot from the previous exercise. So, we will only be filling the blanks when we need to.
The following code accomplishes this.

Fill in the blanks with ad_from_string & static textFill in the blanks with ad_from_string & static text

As these are random descriptions and don’t correspond directly to the keywords we created above, the ad group names would not make sense. When getting such descriptions, it is important to make sure that each one is mapped to the same product name you used for the keywords table and this way you make sure that all your campaigns are complete with keywords and ads.

Some ad slots have text in them, but very little; this depends on your judgment. You can keep them as is, or you can change the rule in the last code that we used to fill in the blanks. Instead of checking if a slot is empty, we can instead check if the length of the slot is less than a certain number of characters. 

Summary

Let me summarize the process of creating the two main tables for keywords and ads. 

  1. Get product names and their URLs (optionally get descriptions as well); this would become your products list.
  2. Research/think of verbs/words that convey the intention you are targeting
    words = [‘buy’, ‘price’, ‘shop’, etc…]
  3. Generate the keywords with one line of code:
    adv.kw_generate(products, words)
  4. Create the ads:

    Template for creating the ads table with ad_createTemplate for creating the ads table with ad_create

  5. Repeat the last step to come up with a few versions/variations.
  6. (Optional) if you have descriptions, use adv.ad_from_string to split descriptions to sub-strings.
  7. (Recommended) use the same technique to build sitelinks and other ad extensions.
  8. Set your campaign settings and bids, and Launch! 





Source link

Leave a Reply