# How MoneyPrinterV2 Outreach Finds Local Businesses via Google Maps Scraping

> Learn how MoneyPrinterV2 Outreach uses Google Maps scraping to find local businesses and automate personalized email campaigns. Discover new leads easily.

- Repository: [FujiwaraChoki/MoneyPrinterV2](https://github.com/FujiwaraChoki/MoneyPrinterV2)
- Tags: how-to-guide
- Published: 2026-03-20

---

**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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) using helper functions defined in [`src/config.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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

```python
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

```python
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

```python
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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/src/status.py)** – Logging utilities for colored console output during the outreach workflow.
- **[`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) and accessed through [`src/config.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/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`.