Blog Migration Automation (Redux)

🛠️ Blog Migration Tool (Portfolio Project)

This custom-built tool automates the migration of blog posts from What Is Alex Thinking to my WordPress site at Payne Enterprises. It utilizes the WordPress REST API, ChromeDriver, and Python scripting to scrape, process, format, and post content seamlessly.

Key Features:

  • 🔎 Scrapes featured blog posts using Selenium
  • 🧠 Prevents duplicates with an SQLite tracking database
  • 🎨 Formats content using Bootstrap 5.3 and post wrappers
  • 📤 Uploads each post via the WordPress REST API
  • 🖼️ Downloads and optimizes featured images

Highlighted Code: main.py

def run_migration():
    """Coordinates the migration process step-by-step."""

    # Remove temporary database if it exists from a previous run
    if os.path.exists("temp.db"):
        os.remove("temp.db")

    # Ensure the main database for tracking migrations is initialized
    initialize_db()

    # Scrape the homepage for available blog posts
    posts = scrape_homepage()
    if not posts:
        logging.warning("No posts found on homepage.")
        return

    # Temporary storage during current run
    temp_db = TempStorage()

    for post in posts:
        if is_post_migrated(post["url"]):
            logging.info(f"Skipping (already migrated): {post['title']}")
            continue

        logging.info(f"Scraping: {post['title']}")
        full_post = scrape_post_content(post["url"])
        if not full_post:
            logging.error(f"Failed to scrape: {post['url']}")
            continue

        temp_db.save_post(full_post)

        # Format post into structure suitable for WordPress
        formatted = format_post_content(full_post)

        # Attempt to upload and mark as migrated if successful
        if upload_post(formatted):
            mark_post_as_migrated(post["url"])
            logging.info(f"Uploaded: {post['title']}")
        else:
            logging.error(f"Failed to upload: {post['title']}")

    # Clean up temporary storage
    temp_db.close()
    if os.path.exists("temp.db"):
        os.remove("temp.db")

Technologies: Python 3.7, Selenium, BeautifulSoup, SQLite, WordPress REST API, Bootstrap 5.3

Codebase is clean, modular, and ready to scale with additional features like image gallery support or multi-blog ingestion.


📁 GitHub Repository

💡 Origin Story

If you haven’t read by now, I was recently laid off from my previous position. Save the condolences and well-wishes—
I had one foot out the door anyway. To be honest, getting a severance check to walk away seemed rather kind after
the initial sting of the breakup wore off.

That said, I didn’t get to bring much with me—just a few personal items from my old machine and zero access to the
100+ automation scripts I’d cobbled together over 6 years. That was a tough pill to swallow.

One of my more impactful contributions was a tool we called “Mass Migration Tool” (aka Miami Lakes).
It was used to migrate dozens—or sometimes hundreds—of blog posts and content pages from a client’s older website to our
custom platform. Most of these migrations were done manually by our dev team, often capped at 10–20 pages. But now and then,
a client would pay extra to migrate 50, 75, or even 100+ pages.

That’s where Miami Lakes came in—designed to reduce the tedious, manual work for developers when those big migrations
came in. It was a timesaver and a sanity-saver.

This project is my spiritual recreation of that tool, rebuilt from scratch and customized to fit my workflow. If you’ve read
this far… you’re a good egg 🥚. I appreciate you. Stick around for my next project post. Until then — insert catchphrase here.

From Our Blogs

Apr 24
Section 8: Conclusion

Next Steps After completing the foundational steps for launching an e-commerce business, learners are encouraged to apply their… Read more

Apr 24
Section 7: Post Sale

Understand Fulfillment Fulfillment refers to the process of shipping products to customers. Entrepreneurs can either ship products themselves… Read more