<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carllowman</title>
    <description>The latest articles on DEV Community by Carllowman (@carllowman).</description>
    <link>https://dev.to/carllowman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3940242%2Fc93d84e8-d6d2-41fc-9bdc-bedf4c26481e.png</url>
      <title>DEV Community: Carllowman</title>
      <link>https://dev.to/carllowman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carllowman"/>
    <language>en</language>
    <item>
      <title>Boost Rich Results with Automated JSON-LD Schema for Blogs</title>
      <dc:creator>Carllowman</dc:creator>
      <pubDate>Fri, 05 Jun 2026 05:45:48 +0000</pubDate>
      <link>https://dev.to/carllowman/boost-rich-results-with-automated-json-ld-schema-for-blogs-5hl9</link>
      <guid>https://dev.to/carllowman/boost-rich-results-with-automated-json-ld-schema-for-blogs-5hl9</guid>
      <description>&lt;p&gt;Just built a quick script to generate JSON-LD schema for my blog posts automatically. No more manual copy-paste from Google's Structured Data Testing Tool.&lt;/p&gt;

&lt;p&gt;The idea: parse the article's title, description, publish date, and author from frontmatter, then output a valid &lt;code&gt;Article&lt;/code&gt; schema.&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
import frontmatter&lt;br&gt;
import json&lt;/p&gt;

&lt;p&gt;def generate_article_schema(post):&lt;br&gt;
    schema = {&lt;br&gt;
        "&lt;a class="mentioned-user" href="https://dev.to/context"&gt;@context&lt;/a&gt;": "&lt;a href="https://schema.org" rel="noopener noreferrer"&gt;https://schema.org&lt;/a&gt;",&lt;br&gt;
        "@type": "Article",&lt;br&gt;
        "headline": post['title'],&lt;br&gt;
        "description": post.get('description', ''),&lt;br&gt;
        "datePublished": post['date'],&lt;br&gt;
        "author": {&lt;br&gt;
            "@type": "Person",&lt;br&gt;
            "name": post['author']&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
    return json.dumps(schema, indent=2)&lt;/p&gt;

&lt;h1&gt;
  
  
  Example usage
&lt;/h1&gt;

&lt;p&gt;post = frontmatter.load('my-post.md')&lt;br&gt;
schema = generate_article_schema(post.metadata)&lt;br&gt;
print(schema)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdok3nnswqbu39b5h0fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdok3nnswqbu39b5h0fw.png" alt=" " width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This handles basic articles, but for richer types like FAQ, Recipe, or Product, you need more fields. I've been using SERPSpur's Schema Markup Generator to handle those complex cases — it outputs clean JSON-LD that passes validation.&lt;/p&gt;

&lt;p&gt;The biggest benefit? Google started showing my posts in rich results within a week. Traffic from featured snippets went up by about 15%.&lt;/p&gt;

&lt;p&gt;What schema types have you found most impactful for SEO?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://serpspur.com" rel="noopener noreferrer"&gt;https://serpspur.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>json</category>
      <category>changelog</category>
      <category>seo</category>
    </item>
    <item>
      <title>How to Handle Location Spoofing for Accurate Local SEO Testing</title>
      <dc:creator>Carllowman</dc:creator>
      <pubDate>Thu, 04 Jun 2026 04:28:12 +0000</pubDate>
      <link>https://dev.to/carllowman/how-to-handle-location-spoofing-for-accurate-local-seo-testing-4d0d</link>
      <guid>https://dev.to/carllowman/how-to-handle-location-spoofing-for-accurate-local-seo-testing-4d0d</guid>
      <description>&lt;p&gt;If you've ever worked on local SEO campaigns, you've probably noticed that search results can vary dramatically depending on where the searcher is located.&lt;/p&gt;

&lt;p&gt;A business may rank #1 in one neighborhood but disappear from the top results just a few miles away. This makes testing local search visibility challenging, especially when you're trying to optimize rankings across multiple locations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Location Matters in Search Results
&lt;/h2&gt;

&lt;p&gt;Google personalizes search results based on several factors, including:&lt;/p&gt;

&lt;p&gt;User location&lt;br&gt;
Search history&lt;br&gt;
Device type&lt;br&gt;
Language settings&lt;br&gt;
Local intent signals&lt;/p&gt;

&lt;p&gt;For example, searching for "best coffee shop" in New York will return completely different results than searching for the same term in Los Angeles.&lt;/p&gt;

&lt;p&gt;This creates a challenge for SEO professionals who need accurate ranking data from locations they aren't physically present in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traditional Methods for Testing Local Rankings
&lt;/h2&gt;

&lt;p&gt;In the past, many SEOs relied on:&lt;/p&gt;

&lt;p&gt;VPN services&lt;br&gt;
Browser location settings&lt;br&gt;
Incognito mode&lt;br&gt;
Local proxies&lt;/p&gt;

&lt;p&gt;While these methods can help, they often introduce inconsistencies and don't always replicate actual local search experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Approach to Location Spoofing
&lt;/h2&gt;

&lt;p&gt;When testing local search results, I focus on simulating searches from specific cities, regions, and languages while minimizing personalization factors.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;1. Define the Target Location&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;Dallas, Texas&lt;br&gt;
London, United Kingdom&lt;br&gt;
Sydney, Australia&lt;br&gt;
*&lt;em&gt;2. Remove Personalization&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Use:&lt;/p&gt;

&lt;p&gt;Incognito mode&lt;br&gt;
Logged-out browser sessions&lt;br&gt;
Cleared cookies and cache&lt;br&gt;
*&lt;em&gt;3. Simulate Local Searches&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Location spoofing tools can emulate searches from different cities, regions, and languages without requiring physical presence in those locations.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;This helps analyze:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Local Pack rankings&lt;br&gt;
Organic rankings&lt;br&gt;
Competitor visibility&lt;br&gt;
Geographic ranking fluctuations&lt;br&gt;
Example: Automating Local Search Checks with Python&lt;/p&gt;

&lt;p&gt;The following example demonstrates how you might automate location-based SERP testing using a location-spoofing service or API.&lt;/p&gt;

&lt;p&gt;import requests&lt;/p&gt;

&lt;p&gt;keyword = "best coffee shop"&lt;br&gt;
location = "New York, NY"&lt;/p&gt;

&lt;p&gt;payload = {&lt;br&gt;
    "keyword": keyword,&lt;br&gt;
    "location": location,&lt;br&gt;
    "language": "en",&lt;br&gt;
    "country": "US"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;response = requests.post(&lt;br&gt;
    "&lt;a href="https://api.example.com/local-search" rel="noopener noreferrer"&gt;https://api.example.com/local-search&lt;/a&gt;",&lt;br&gt;
    json=payload&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;results = response.json()&lt;/p&gt;

&lt;p&gt;print(f"Keyword: {keyword}")&lt;br&gt;
print(f"Location: {location}")&lt;/p&gt;

&lt;p&gt;for rank, result in enumerate(results["organic_results"], start=1):&lt;br&gt;
    print(f"{rank}. {result['title']}")&lt;br&gt;
    print(f"   URL: {result['url']}")&lt;/p&gt;

&lt;p&gt;This workflow allows you to compare search results from multiple locations without manually changing browser settings each time.&lt;/p&gt;

&lt;p&gt;Example: Compare Rankings Across Multiple Cities&lt;br&gt;
cities = [&lt;br&gt;
    "New York, NY",&lt;br&gt;
    "Chicago, IL",&lt;br&gt;
    "Los Angeles, CA",&lt;br&gt;
    "Houston, TX"&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;keyword = "plumber near me"&lt;/p&gt;

&lt;p&gt;for city in cities:&lt;br&gt;
    payload = {&lt;br&gt;
        "keyword": keyword,&lt;br&gt;
        "location": city&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;response = requests.post(
    "https://api.example.com/local-search",
    json=payload
)

data = response.json()

print(f"\nResults for {city}")
print("-" * 40)

for rank, result in enumerate(data["organic_results"][:5], start=1):
    print(f"{rank}. {result['title']}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This type of automation is especially useful for agencies managing local SEO campaigns across dozens of cities.&lt;/p&gt;

&lt;p&gt;Benefits of Location Spoofing for SEO&lt;br&gt;
Better Local SEO Audits&lt;/p&gt;

&lt;p&gt;You can identify location-specific ranking issues that standard rank tracking often misses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Competitor Analysis
&lt;/h2&gt;

&lt;p&gt;Understand how competitors perform in different markets and uncover opportunities to gain visibility.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://serpspur.com" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yjwnl8yv6z1ii1tswtv.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Google Business Profile Optimization&lt;/p&gt;

&lt;p&gt;Location testing helps verify whether your business appears consistently in targeted areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Accurate Reporting
&lt;/h2&gt;

&lt;p&gt;Clients receive ranking data that reflects actual user experiences rather than generic national rankings.&lt;/p&gt;

&lt;p&gt;Common Mistakes to Avoid&lt;br&gt;
Relying Only on VPNs&lt;/p&gt;

&lt;p&gt;VPNs change your IP address but don't always replicate Google's local search signals accurately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing from a Single Location
&lt;/h2&gt;

&lt;p&gt;Local SEO performance can vary significantly even within the same city.&lt;/p&gt;

&lt;p&gt;Ignoring Language and Region Settings&lt;/p&gt;

&lt;p&gt;Search results can differ based on language preferences and regional targeting.&lt;/p&gt;

&lt;p&gt;Not Tracking Changes Over Time&lt;/p&gt;

&lt;p&gt;Local rankings fluctuate frequently, so regular monitoring is essential.&lt;/p&gt;

&lt;p&gt;Advanced Tip&lt;/p&gt;

&lt;h2&gt;
  
  
  When analyzing local SEO performance, compare:
&lt;/h2&gt;

&lt;p&gt;City-level rankings&lt;br&gt;
ZIP/postal code rankings&lt;br&gt;
Language-specific results&lt;br&gt;
Mobile vs desktop rankings&lt;/p&gt;

&lt;p&gt;This provides a much more accurate picture of your actual visibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Location spoofing has become an essential part of modern local SEO. By simulating searches from different geographic areas, you can uncover ranking opportunities, identify visibility gaps, and make better optimization decisions.&lt;/p&gt;

&lt;p&gt;Whether you're managing a single local business or multiple client campaigns, location-based SERP testing can provide valuable insights that standard rank tracking often misses.&lt;/p&gt;

&lt;p&gt;How do you handle location spoofing for testing search results? Share your workflow and favorite tools in the comments!&lt;/p&gt;

</description>
      <category>localhackday</category>
      <category>python</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Fix Duplicate Content Issues in SEO Using a Simple Python Similarity Checker Script</title>
      <dc:creator>Carllowman</dc:creator>
      <pubDate>Wed, 03 Jun 2026 08:49:24 +0000</pubDate>
      <link>https://dev.to/carllowman/fix-duplicate-content-issues-in-seo-using-a-simple-python-similarity-checker-script-371c</link>
      <guid>https://dev.to/carllowman/fix-duplicate-content-issues-in-seo-using-a-simple-python-similarity-checker-script-371c</guid>
      <description>&lt;p&gt;Struggling with duplicate content across multiple landing pages? I wrote a quick script to compare text similarity using cosine similarity with TF-IDF vectors. Here's how:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
from sklearn.feature_extraction.text import TfidfVectorizer&lt;br&gt;
from sklearn.metrics.pairwise import cosine_similarity&lt;/p&gt;

&lt;p&gt;def check_duplicates(texts):&lt;br&gt;
    vectorizer = TfidfVectorizer()&lt;br&gt;
    tfidf_matrix = vectorizer.fit_transform(texts)&lt;br&gt;
    similarity = cosine_similarity(tfidf_matrix)&lt;br&gt;
    for i in range(len(similarity)):&lt;br&gt;
        for j in range(i+1, len(similarity)):&lt;br&gt;
            if similarity[i][j] &amp;gt; 0.8:&lt;br&gt;
                print(f"High similarity between page {i} and {j}: {similarity[i][j]:.2f}")&lt;/p&gt;

&lt;p&gt;This flagged several pages that needed rewriting. For larger audits, I've been using a tool that automates this analysis. How do you handle duplicate content detection?&lt;/p&gt;

&lt;p&gt;Handle Duplicate Content :  &lt;strong&gt;&lt;a href="https://serpspur.com" rel="noopener noreferrer"&gt;https://serpspur.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>contentwriting</category>
      <category>website</category>
      <category>python</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Checked London Google Rankings While Working Remotely from Tokyo</title>
      <dc:creator>Carllowman</dc:creator>
      <pubDate>Tue, 02 Jun 2026 10:40:58 +0000</pubDate>
      <link>https://dev.to/carllowman/how-i-checked-london-google-rankings-while-working-remotely-from-tokyo-57kl</link>
      <guid>https://dev.to/carllowman/how-i-checked-london-google-rankings-while-working-remotely-from-tokyo-57kl</guid>
      <description>&lt;p&gt;I needed to check how my website ranks for 'plumber London' from a user actually in London. But I'm sitting in a café in Tokyo. Remote work problems, right?&lt;/p&gt;

&lt;p&gt;My quick fix was a bash script that uses curl with custom headers and a geolocation-aware proxy:&lt;/p&gt;

&lt;p&gt;bash&lt;/p&gt;

&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;

&lt;p&gt;QUERY="plumber London"&lt;br&gt;
COUNTRY="GB"&lt;br&gt;
LANGUAGE="en"&lt;br&gt;
PROXY="london-proxy.example.com:8080"&lt;/p&gt;

&lt;p&gt;curl -s -H "Accept-Language: $LANGUAGE" \&lt;br&gt;
     --proxy "http://$PROXY" \&lt;br&gt;
     "&lt;a href="https://www.google.com/search?q=$QUERY&amp;amp;gl=$COUNTRY" rel="noopener noreferrer"&gt;https://www.google.com/search?q=$QUERY&amp;amp;gl=$COUNTRY&lt;/a&gt;" | \&lt;br&gt;
     grep -oP '&lt;br&gt;
]&lt;em&gt;&amp;gt;.&lt;/em&gt;?&lt;br&gt;
' | \&lt;br&gt;
     sed 's/]*&amp;gt;//g'&lt;/p&gt;

&lt;p&gt;This gives me the top results' titles. But maintaining a list of reliable proxies for every city I need to test is a full-time job. I've since moved to a service that provides clean, location-specific search data without the proxy headache.&lt;/p&gt;

&lt;p&gt;**[I needed to check how my website ranks for 'plumber London' from a user actually in London. But I'm sitting in a café in Tokyo. Remote work problems, right?&lt;/p&gt;

&lt;p&gt;My quick fix was a bash script that uses curl with custom headers and a geolocation-aware proxy:&lt;/p&gt;

&lt;p&gt;bash&lt;/p&gt;

&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;

&lt;p&gt;QUERY="plumber London"&lt;br&gt;
COUNTRY="GB"&lt;br&gt;
LANGUAGE="en"&lt;br&gt;
PROXY="london-proxy.example.com:8080"&lt;/p&gt;

&lt;p&gt;curl -s -H "Accept-Language: $LANGUAGE" \&lt;br&gt;
     --proxy "http://$PROXY" \&lt;br&gt;
     "&lt;a href="https://www.google.com/search?q=$QUERY&amp;amp;gl=$COUNTRY" rel="noopener noreferrer"&gt;https://www.google.com/search?q=$QUERY&amp;amp;gl=$COUNTRY&lt;/a&gt;" | \&lt;br&gt;
     grep -oP '&lt;br&gt;
]&lt;em&gt;&amp;gt;.&lt;/em&gt;?&lt;br&gt;
' | \&lt;br&gt;
     sed 's/]*&amp;gt;//g'&lt;/p&gt;

&lt;p&gt;This gives me the top results' titles. But maintaining a list of reliable proxies for every city I need to test is a full-time job. I've since moved to a service that provides clean, location-specific search data without the proxy headache.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://serpspur.com" rel="noopener noreferrer"&gt;https://serpspur.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>beginners</category>
      <category>python</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
