How MoneyPrinterV2 Outreach Finds Local Businesses via Google Maps Scraping

The MoneyPrinterV2 Outreach class automates local business discovery by downloading a Go-based Google Maps scraper, executing it against a user-defined niche, and enriching the results with verified email addresses before dispatching personalized outreach campaigns.

MoneyPrinterV2 is an open-source automation framework designed for content monetization and scalable client acquisition. The platform's outreach module leverages Google Maps scraping to identify potential local business clients, combining a compiled Go binary with Python orchestration to harvest business data at scale. This architecture cleanly separates the heavy web scraping workload from the business logic and email automation components.

Step 1: Initializing the Go-Based Google Maps Scraper

The outreach workflow begins in src/classes/Outreach.py where the Outreach class constructor initializes the scraping environment. The system loads the target niche and email credentials from config.json using helper functions defined in src/config.py.

Loading Configuration and Niche Parameters

The constructor calls get_google_maps_scraper_niche() and get_email_credentials() to retrieve the search parameters and SMTP settings. These values populate self.niche and the email configuration attributes required for later outreach stages.

Downloading and Extracting the Scraper Binary

The unzip_file() method handles acquisition of the Go-based scraper. It downloads the zip archive from the URL stored under the google_maps_scraper key in src/config.py, then extracts the contents while skipping suspicious paths to prevent directory traversal attacks.

Compiling the Go Binary

Once extracted, build_scraper() executes compilation in the scraper directory. The method runs go mod download to fetch dependencies, followed by go build to produce the platform-specific binary—google-maps-scraper on Unix systems or google-maps-scraper.exe on Windows. This compiled binary is what actually interfaces with Google Maps.

Step 2: Executing the Scraping Operation

With the binary compiled, the Python wrapper executes the scraper against the user-defined niche.

Preparing the Niche Input File

The system writes the niche value to a temporary niche.txt file. The Go binary reads this file to determine which business category or search term to query on Google Maps.

Running the Compiled Binary with Timeout Controls

The run_scraper_with_args_for_30_seconds() method launches the compiled binary with the arguments -input niche.txt -results "<output_path>". Although the method name references 30 seconds, the actual timeout is controlled by scraper_timeout in config.json (defaulting to 300 seconds). The method monitors the subprocess and terminates the scraper if it exceeds this duration, returning the path to the generated CSV results file.

Step 3: Processing Results and Enriching Contact Data

Once the scraper generates its CSV output, the Python module processes and enriches the data before initiating contact.

Parsing the CSV Output

The get_items_from_file() method reads the CSV results file located at the path returned by get_results_cache_path(). It skips the header row and returns a list of rows, where each row contains business details including name, address, phone number, website, and email fields.

Extracting Emails from Business Websites

For each business row, the code extracts the first URL beginning with http. If requests.get returns a 200 status code, set_email_for_website() crawls the website content and extracts the first email address using a regular expression. This discovered email is appended to the corresponding CSV row, ensuring the outreach list contains valid contact information.

Sending Automated Outreach Messages

With verified emails collected, the system initializes yagmail.SMTP using the credentials loaded earlier from config.json. It sends personalized messages to each business email address using the subject template stored in outreach_message_subject and the body template from outreach_message_body_file, completing the automated outreach pipeline.

How the Google Maps Scraper Works Internally

The repository distributes the Google Maps scraper as a zip archive containing Go source code rather than a pre-built binary. This design delegates the actual web scraping to a compiled Go program while Python handles orchestration. The Go binary contacts Google Maps directly, queries for businesses matching the niche specified in niche.txt, and writes structured data to a CSV file. The Python wrapper never parses Google Maps HTML directly; it merely manages the lifecycle of the external scraper process and consumes its output.

Practical Implementation Examples

Basic Outreach Workflow

from src.classes.Outreach import Outreach

# Initialize the outreach engine

outreach = Outreach()

# Execute full pipeline: scrape, enrich, and send emails

outreach.start()

Isolated Scraper Execution

from src.classes.Outreach import Outreach
from src.config import get_google_maps_scraper_zip_url, get_results_cache_path, get_scraper_timeout

o = Outreach()

# Download and extract the Go scraper

o.unzip_file(get_google_maps_scraper_zip_url())

# Compile the binary

o.build_scraper()

# Run with timeout control

o.run_scraper_with_args_for_30_seconds(
    f'-input niche.txt -results "{get_results_cache_path()}"',
    timeout=get_scraper_timeout()
)

Email Extraction Helper

from src.classes.Outreach import Outreach

out = Outreach()

# Extract email from specific website and update CSV

out.set_email_for_website(
    index=0,
    website="https://example.com",
    output_file="results.csv"
)

Key Files and Functions

  • src/classes/Outreach.py – Core orchestration class containing unzip_file(), build_scraper(), run_scraper_with_args_for_30_seconds(), get_items_from_file(), and set_email_for_website().
  • src/config.py – Configuration management including get_google_maps_scraper_niche(), get_email_credentials(), get_google_maps_scraper_zip_url(), and get_scraper_timeout().
  • src/status.py – Logging utilities for colored console output during the outreach workflow.
  • config.json – User-editable configuration storing the scraper URL, niche parameters, SMTP credentials, and message templates.

Summary

  • The Outreach class in src/classes/Outreach.py orchestrates the entire workflow from scraping to email delivery.
  • The system uses a Go-based external binary rather than Python-based HTML parsing to extract Google Maps data, compiled at runtime via build_scraper().
  • Configuration is centralized in config.json and accessed through src/config.py, controlling the niche, scraper timeout, and email credentials.
  • Post-processing involves CSV parsing via get_items_from_file() and website crawling via set_email_for_website() to enrich business records with contact emails.
  • Delivery uses yagmail.SMTP to send personalized messages based on templates defined in the configuration.

Frequently Asked Questions

How does MoneyPrinterV2 avoid using pre-built binaries for Google Maps scraping?

MoneyPrinterV2 downloads the scraper source code as a zip archive defined in config.json under the google_maps_scraper key. The unzip_file() method extracts this archive, and build_scraper() compiles the Go code locally using go mod download and go build. This approach ensures the binary matches the host architecture and avoids trusting pre-compiled executables.

What controls the duration of the Google Maps scraping operation?

The run_scraper_with_args_for_30_seconds() method accepts a timeout parameter that defaults to the value stored in config.json under scraper_timeout (typically 300 seconds). The method monitors the subprocess and terminates the scraper if it exceeds this duration, returning control to the Python orchestration layer regardless of whether the scrape completed.

How does the system extract email addresses from discovered business websites?

After parsing the CSV output via get_items_from_file(), the code extracts the first URL beginning with http from each business record. The set_email_for_website() method then performs an HTTP GET request to that URL, crawls the HTML content, and applies a regular expression to capture the first email address found. This discovered email is appended to the corresponding CSV row for subsequent outreach.

Can the outreach messages be customized per business category?

Yes. The Outreach class reads message templates from config.json using the keys outreach_message_subject and outreach_message_body_file. The subject line supports dynamic insertion of business-specific variables, and the body content is loaded from an external file path defined in the configuration. This allows users to maintain separate message templates for different niches and personalize content before sending via yagmail.SMTP.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →