     [Blog](https://scrapfly.io/blog)   /  [python](https://scrapfly.io/blog/tag/python)   /  [How to Scrape Homegate.ch Real Estate Property Data](https://scrapfly.io/blog/posts/how-to-scrape-homegate-ch-real-estate-property-data)   # How to Scrape Homegate.ch Real Estate Property Data

 by [Mazen Ramadan](https://scrapfly.io/blog/author/mazen) May 18, 2026 18 min read [\#python](https://scrapfly.io/blog/tag/python) [\#real-estate](https://scrapfly.io/blog/tag/real-estate) [\#scrapeguide](https://scrapfly.io/blog/tag/scrapeguide) 

 [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-homegate-ch-real-estate-property-data "Share on LinkedIn")    

 

 

   

   **Web Scraping API — Anti-Bot Bypass**Bypass any anti-scraper system and automatically resolve JavaScript and fingerprint challenges.

 

 [ Learn More  ](https://scrapfly.io/products/web-scraping-api#features) [  Docs ](https://scrapfly.io/docs/scrape-api/getting-started#features) 

 

 

If your Homegate.ch scraper stopped returning data in 2025, Homegate's frontend migration is the most likely cause. Homegate moved property pages from `window.__INITIAL_STATE__` to `window.__PINIA_INITIAL_STATE__` (Vue 3 / Pinia) and dropped the `/de/` locale prefix from all URLs. Any scraper written before that change now hits empty results or 403 errors on property pages, even if the code was working perfectly before.

In this guide, you'll learn how to extract listing data from both Homegate page types. Property pages use the new Pinia state store; search pages still use the older `__INITIAL_STATE__` variable. You'll also see how to handle the rendering requirement and paginate across search results concurrently.



[**Latest Homegate.ch Scraper Code**github.com/scrapfly/scrapfly-scrapers/tree/main/homegate-scraper](https://github.com/scrapfly/scrapfly-scrapers/tree/main/homegate-scraper)

## Key Takeaways

- **Property pages migrated to Pinia (Vue 3) in 2025**, breaking older scrapers. Listing data now lives in `window.__PINIA_INITIAL_STATE__` instead of `__INITIAL_STATE__`. Extract the JSON with regex and walk to `data["listing"]["listing"]`.
- **JavaScript rendering is now mandatory.** Plain HTTP requests return 403 or empty HTML. Use a headless browser or a scraping API with `render_js=True` and a current Chrome User-Agent (131+).
- **Search pages were not migrated** and still use `window.__INITIAL_STATE__`. Each page returns 20 listings; `pageCount` tells you how far to paginate using the `ep` query parameter.
- **URLs dropped the `/de/` locale prefix.** Property pages now follow the pattern `https://www.homegate.ch/rent/<id>`.
- **For production real estate scraping** without managing a headless browser fleet, Swiss residential proxies, and ongoing anti-bot b 4ypass, [Scrapfly's Real Estate Web Scraping API](https://scrapfly.io/use-case/real-estate-web-scraping) handles all three in a single `ScrapeConfig`, so the Pinia parsing logic from this guide drops in unchanged.

**Get web scraping tips in your inbox**Trusted by 100K+ developers and 30K+ enterprises. Unsubscribe anytime.







## Why Scrape Homegate.ch?

Homegate.ch is Switzerland's leading real estate marketplace, aggregating thousands of rental and sale listings from agencies and private sellers across every canton. Scraping Homegate gives you market data for price tracking, investment research, and competitive analysis that you can't gather manually at any useful scale.

Each listing contains structured data: price, address with geo coordinates, living space, room count, property category, year built, energy class, and a photo gallery. Both sales and rental channels expose the same JSON schema. One parser covers both offer types.

Typical uses include monitoring rent trends across cantons, comparing price-per-square-metre by neighbourhood, and tracking how long listings stay active before the owner removes them. The data is publicly visible and machine-readable in the page source. The main challenges are the JavaScript rendering requirement and the two different hidden state formats that Homegate uses on different page types.

The data you need is sitting in the HTML source on every page request. The techniques in the following sections pull it out directly.



## Project Setup

The scraper uses four Python packages. Install three; `asyncio` and `re` ship with Python.

- [httpx](https://pypi.org/project/httpx/): async HTTP client for the plain Python code path
- [parsel](https://pypi.org/project/parsel/): XPath and CSS selectors for finding script tags in the returned HTML
- [scrapfly-sdk](https://pypi.org/project/scrapfly-sdk/): the Scrapfly SDK used in the Scrapfly tab examples

Install all three in one command:

shell```shell
pip install httpx parsel scrapfly-sdk
```



Homegate.ch requires JavaScript rendering. A plain `httpx` or `requests` call returns a 403 Forbidden response or a bare HTML shell that contains none of the Pinia or INITIAL\_STATE script tags. The parsing examples below illustrate the logic, but to fetch Homegate pages you'll need either a headless browser or the Scrapfly SDK with `render_js=True`. Our [browser scraping guide](https://scrapfly.io/blog/posts/scraping-using-browsers) covers the Playwright path if you prefer to manage your own browser.

With the packages installed, you can build the property page parser.



## How to Scrape Homegate.ch Property Pages?

Homegate.ch property pages store all listing data as structured JSON inside a `window.__PINIA_INITIAL_STATE__` script tag in the HTML. The script tag is invisible to users but readable in the page source. It's the same JSON object Homegate's Vue 3 app uses to hydrate the page on load. Fetching and parsing that JSON gives you every field the page renders, plus dozens more that aren't shown in the UI.

### Locating Property Data in the Pinia State

Open a current Homegate property URL (for example `https://www.homegate.ch/rent/4002086534`) in Chrome. Press F12 to open DevTools and switch to the Elements tab. Use Ctrl+F to search for `__PINIA_INITIAL_STATE__`. The script tag appears near the bottom of the `<body>`. It contains the full listing object as a JSON string assigned to `window.__PINIA_INITIAL_STATE__`.



Homegate.ch property pageThe source view below shows what that assignment looks like in the HTML. Line 4 marks exactly where `window.__PINIA_INITIAL_STATE__` gets its value.

This variable previously used `window.__INITIAL_STATE__`. If your older scraper targets that variable on property pages, it now returns `None`. Homegate removed it from property pages when the frontend migrated. Switch the XPath to target `__PINIA_INITIAL_STATE__` and the data comes back. For the general technique of extracting JSON from script tags, see [How to Scrape Hidden Web Data](https://scrapfly.io/blog/posts/how-to-scrape-hidden-web-data).

### Parsing the Pinia JSON with Python

The `parse_property_page()` function uses XPath to find the script tag and then a regex to pull the JSON object out of it. You need the regex because XPath `text()` returns only the script body without the closing `</script>` tag, so the JSON boundary isn't clean. Concatenating `</script>` before matching gives the regex a reliable end boundary to match against.



Python

Scrapfly

python```python
import asyncio
import json
import re
from typing import Dict, List
from httpx import AsyncClient, Response
from parsel import Selector

client = AsyncClient(
    headers={
        # Current Chrome user agent to match a real browser
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
        "Accept-Language": "en-GB,en;q=0.9,de-CH;q=0.8",
    },
    follow_redirects=True,
    http2=True,
    timeout=30,
)


def parse_property_page(response: Response) -> Dict:
    """Extract the Pinia state JSON from a Homegate property page."""
    selector = Selector(response.text)
    # Find the <script> tag that assigns window.__PINIA_INITIAL_STATE__
    script = selector.xpath(
        "//script[contains(text(),'__PINIA_INITIAL_STATE__')]/text()"
    ).get()
    if not script:
        return None
    # Concatenate </script> so the regex has a clean end boundary
    match = re.search(
        r"window\.__PINIA_INITIAL_STATE__\s*=\s*(\{.+?\})\s*;?\s*</script>",
        script + "</script>",
        re.DOTALL,
    )
    if not match:
        return None
    return json.loads(match.group(1))
```





python```python
import asyncio
import json
import re
from typing import Dict, List
from scrapfly import ScrapeApiResponse, ScrapeConfig, ScrapflyClient

# Homegate requires JS rendering and an anti-bot bypass
BASE_CONFIG = {
    "asp": True,
    "country": "CH",
    "render_js": True,
}

scrapfly = ScrapflyClient(key="YOUR_SCRAPFLY_KEY")


def parse_property_page(response: ScrapeApiResponse) -> Dict:
    """Extract the Pinia state JSON from a Homegate property page."""
    script = response.selector.xpath(
        "//script[contains(text(),'__PINIA_INITIAL_STATE__')]/text()"
    ).get()
    if not script:
        return None
    match = re.search(
        r"window\.__PINIA_INITIAL_STATE__\s*=\s*(\{.+?\})\s*;?\s*</script>",
        script + "</script>",
        re.DOTALL,
    )
    if not match:
        return None
    return json.loads(match.group(1))
```







The XPath `//script[contains(text(),'__PINIA_INITIAL_STATE__')]` targets the one script block among many that carries the state assignment. Pass `re.DOTALL` because the JSON value spans multiple lines. For a deeper look at [XPath selectors in Python](https://scrapfly.io/blog/posts/parsing-html-with-xpath), see our dedicated parsing guide.

With the parser ready, scrape multiple property URLs concurrently:



Python

Scrapfly

python```python
async def scrape_properties(urls: List[str]) -> List[Dict]:
    """Scrape Homegate property pages concurrently."""
    to_scrape = [client.get(url) for url in urls]
    properties = []
    for response in asyncio.as_completed(to_scrape):
        data = parse_property_page(await response)
        # Walk to the listing object; skip pages that no longer have a listing
        try:
            properties.append(data["listing"]["listing"])
        except (KeyError, TypeError):
            print("expired property page")
    return properties
```





python```python
from scrapfly import ScrapflyScrapeError


async def scrape_properties(urls: List[str]) -> List[Dict]:
    """Scrape Homegate property pages concurrently through Scrapfly."""
    to_scrape = [ScrapeConfig(url, **BASE_CONFIG) for url in urls]
    properties = []
    async for response in scrapfly.concurrent_scrape(to_scrape):
        # concurrent_scrape yields ScrapflyScrapeError on transient failures
        if isinstance(response, ScrapflyScrapeError):
            print(f"scrape failed: {response}")
            continue
        data = parse_property_page(response)
        try:
            properties.append(data["listing"]["listing"])
        except (KeyError, TypeError):
            print("expired property page")
    return properties
```







Scrapfly

#### Scale your web scraping effortlessly

Scrapfly handles proxies, browsers, and anti-bot bypass — so you can focus on data.

[Try Free →](https://scrapfly.io/register)The `try/except (KeyError, TypeError)` block keeps one expired listing from breaking the whole batch. Expired listing URLs often redirect to a search page that has no `listing` key in the Pinia store. For background on async scraping performance and concurrency patterns, see our [web scraping speed guide](https://scrapfly.io/blog/posts/web-scraping-speed).

Run the scraper on a handful of current Homegate rentals:

python```python
if __name__ == "__main__":
    properties = asyncio.run(scrape_properties([
        "https://www.homegate.ch/rent/4002086534",
        "https://www.homegate.ch/rent/4002879785",
        "https://www.homegate.ch/rent/4002086532",
    ]))
    print(json.dumps(properties, indent=2))
```



Each result is the full listing object from Homegate's Pinia store. Here's a trimmed sample showing the most commonly used fields:

json```json
[
  {
    "id": "4002086534",
    "categories": ["APARTMENT", "FLAT"],
    "offerType": "RENT",
    "address": {
      "country": "CH",
      "locality": "Bern",
      "postalCode": "3007",
      "street": "Beispielstrasse 12",
      "geoCoordinates": {
        "latitude": 46.945,
        "longitude": 7.445
      }
    },
    "characteristics": {
      "numberOfRooms": 3.5,
      "livingSpace": 82,
      "yearBuilt": 1965,
      "hasBalcony": true,
      "hasElevator": true
    },
    "prices": {
      "rent": {"gross": 1650, "interval": "MONTH"},
      "currency": "CHF"
    },
    "lister": {"legalName": "Homegate AG"},
    "localization": {
      "primary": "de",
      "de": {"text": {"title": "3.5 Zimmer Wohnung in Bern"}}
    }
  }
]
```



The full Pinia payload contains image galleries, extra localizations, and 80+ metadata fields you can add to your schema. Property pages give you depth on a single listing. For gathering IDs across a whole city or canton first, the search pages are the entry point.

[How to Scrape Hidden Web DataThe visible HTML doesn't always represent the whole dataset available on the page. In this article, we'll be taking a look at scraping of hidden web data. What is it and how can we scrape it using Python?](https://scrapfly.io/blog/posts/how-to-scrape-hidden-web-data)



## How to Scrape Homegate.ch Search Pages?

Homegate.ch search pages still use the older `window.__INITIAL_STATE__` variable. The search frontend wasn't migrated when the property pages moved to Pinia. The JSON path `data["resultList"]["search"]["fullSearch"]["result"]["listings"]` gives you up to 20 property cards per page, and `result["pageCount"]` tells you how many total pages the query has.

### Understanding Homegate.ch Search URL Structure

Homegate's search URLs follow a clean pattern: `https://www.homegate.ch/<rent|buy>/real-estate/<location-segment>/matching-list`. Homegate dropped the `/de/` locale prefix. Any URL that still includes it returns a redirect or empty results, so remove it from existing code.

Pagination uses the `ep` query parameter. Page 2 of Bern rentals looks like this:

text```text
https://www.homegate.ch/rent/real-estate/city-bern/matching-list?ep=2
```



Swap `rent` for `buy` to get sales listings. Swap the location segment (`city-bern`) for other cantons or cities you care about.

Swap `rent` for `buy` to get sales listings. Use any city or canton slug in place of `city-bern`. Busy locations like Zurich return 20–30 pages per query.



Search pages use `window.__INITIAL_STATE__` instead of Pinia. The highlighted line below shows the script tag that holds all the result data.



### How Does Homegate.ch Search Pagination Work?

The `parse_next_data()` function uses XPath to find the `__INITIAL_STATE__` script tag, then splits on the first `=` to isolate the JSON string. Splitting on `=` is more solid than stripping a prefix string. It doesn't break if Homegate ever adds whitespace around the assignment. For more on [CSS selectors and XPath](https://scrapfly.io/blog/posts/parsing-html-with-css), see our parsing guide.



Python

Scrapfly

python```python
import asyncio
import json
from typing import Dict, List, Literal
from httpx import AsyncClient, Response
from parsel import Selector


def parse_next_data(response: Response) -> Dict:
    """Extract the __INITIAL_STATE__ JSON from a Homegate search page."""
    selector = Selector(response.text)
    script = selector.xpath(
        "//script[contains(text(),'window.__INITIAL_STATE__')]/text()"
    ).get()
    if not script:
        return None
    # Split on first '=' and parse the JSON that follows
    json_text = script.split("=", 1)[1].strip().rstrip(";")
    return json.loads(json_text)


async def scrape_search(
    query_type: Literal["rent", "buy"] = "rent",
    location: str = "city-bern",
    scrape_all_pages: bool = True,
    max_scrape_pages: int = 5,
) -> List[Dict]:
    """Scrape Homegate search results with pagination."""
    url = f"https://www.homegate.ch/{query_type}/real-estate/{location}/matching-list"
    first_page = await client.get(url)
    data = parse_next_data(first_page)["resultList"]["search"]["fullSearch"]["result"]
    search_data = data["listings"]
    total_pages = data["pageCount"]
    print(f"scraped page 1, total {total_pages} pages available")

    # Cap how many pages we scrape
    last_page = total_pages if scrape_all_pages else min(max_scrape_pages, total_pages)
    other_pages = [client.get(f"{url}?ep={page}") for page in range(2, last_page + 1)]
    for response in asyncio.as_completed(other_pages):
        page_data = parse_next_data(await response)
        search_data.extend(
            page_data["resultList"]["search"]["fullSearch"]["result"]["listings"]
        )
    print(f"scraped {len(search_data)} listings from {last_page} pages")
    return search_data
```





python```python
import asyncio
import json
from typing import Dict, List, Literal
from scrapfly import ScrapeApiResponse, ScrapeConfig, ScrapflyClient, ScrapflyScrapeError


def parse_next_data(response: ScrapeApiResponse) -> Dict:
    """Extract the __INITIAL_STATE__ JSON from a Homegate search page."""
    script = response.selector.xpath(
        "//script[contains(text(),'window.__INITIAL_STATE__')]/text()"
    ).get()
    if not script:
        return None
    json_text = script.split("=", 1)[1].strip().rstrip(";")
    return json.loads(json_text)


async def scrape_search(
    query_type: Literal["rent", "buy"] = "rent",
    location: str = "city-bern",
    scrape_all_pages: bool = True,
    max_scrape_pages: int = 5,
) -> List[Dict]:
    """Scrape Homegate search results through Scrapfly."""
    url = f"https://www.homegate.ch/{query_type}/real-estate/{location}/matching-list"
    first_page = await scrapfly.async_scrape(ScrapeConfig(url, **BASE_CONFIG))
    data = parse_next_data(first_page)["resultList"]["search"]["fullSearch"]["result"]
    search_data = data["listings"]
    total_pages = data["pageCount"]

    last_page = total_pages if scrape_all_pages else min(max_scrape_pages, total_pages)
    other_pages = [
        ScrapeConfig(f"{url}?ep={page}", **BASE_CONFIG)
        for page in range(2, last_page + 1)
    ]
    async for response in scrapfly.concurrent_scrape(other_pages):
        # Skip pages where the anti-bot bypass hit a transient limit
        if isinstance(response, ScrapflyScrapeError):
            print(f"page scrape failed: {response}")
            continue
        page_data = parse_next_data(response)
        search_data.extend(
            page_data["resultList"]["search"]["fullSearch"]["result"]["listings"]
        )
    return search_data
```







The strategy: scrape page 1 to get `pageCount`, then fan out across the remaining pages concurrently. Each page returns up to 20 listing cards.

Run the search scraper:

python```python
if __name__ == "__main__":
    listings = asyncio.run(scrape_search(
        query_type="rent",
        location="city-bern",
        scrape_all_pages=False,
        max_scrape_pages=2,
    ))
    print(f"Got {len(listings)} listings")
    print(json.dumps(listings[0], indent=2))
```



Each listing card from the search results looks like this:

json```json
{
  "listingType": {"type": "PREMIUM"},
  "id": "4002086531",
  "listing": {
    "id": "4002086531",
    "offerType": "RENT",
    "address": {
      "locality": "Bern",
      "postalCode": "3012",
      "street": "Forstweg 71"
    },
    "categories": ["APARTMENT", "ATTIC_FLAT"],
    "characteristics": {
      "numberOfRooms": 5.5,
      "livingSpace": 150,
      "yearBuilt": 1972,
      "hasBalcony": true,
      "hasElevator": true
    },
    "prices": {
      "rent": {"gross": 4240, "interval": "WEEK"},
      "currency": "CHF"
    }
  }
}
```



The `id` on each card is the same ID you can plug into `https://www.homegate.ch/rent/<id>` to pull the full listing through the Pinia path in the previous section. You now have the full data path: search pages to discover IDs at scale, property pages to pull complete listings. The remaining challenge is getting past Homegate's anti-bot layer.

## How to Avoid Homegate.ch Web Scraping Blocking?

Homegate.ch blocks standard HTTP requests with anti-bot protection. Without JavaScript rendering and proper browser fingerprinting, you get a 403 Forbidden response or a bare HTML page with no `__PINIA_INITIAL_STATE__` or `__INITIAL_STATE__` script tags at all. The listing data isn't in the response until the full browser execution cycle runs.

Two approaches reliably handle the blocking: a headless browser that runs the full JS pipeline, or a scraping API that handles rendering for you. Either way, four settings matter most:

- **Turn on JavaScript rendering** through a headless browser (Playwright, Selenium) or a scraping API's `render_js=True` option
- **Route through a Swiss IP** (`country="CH"`) since Homegate may restrict access based on request origin
- **Use a current Chrome User-Agent** matching Chrome 131+ and set `Accept-Language` to include `de-CH` to match a typical Swiss visitor fingerprint
- **Rotate proxies** for concurrent scraping at scale. See our [IP blocking guide](https://scrapfly.io/blog/posts/how-to-avoid-web-scraping-blocking-ip-addresses) and [proxy rotation patterns](https://scrapfly.io/blog/posts/how-to-rotate-proxies-in-web-scraping)

Here's the Scrapfly pattern for a single Homegate request:

python```python
from scrapfly import ScrapflyClient, ScrapeConfig

scrapfly = ScrapflyClient(key="YOUR_SCRAPFLY_KEY")

result = scrapfly.scrape(ScrapeConfig(
    url="https://www.homegate.ch/rent/4002086534",
    asp=True,          # Anti-Scraping Protection bypass
    country="CH",      # Swiss residential proxy
    render_js=True,    # Required; Homegate blocks plain HTTP
))
selector = result.selector
```



These three flags (`asp`, `country`, `render_js`) are the minimum config for Homegate. For background on header-based blocking, see our [headers guide](https://scrapfly.io/blog/posts/how-to-avoid-web-scraping-blocking-headers). For the full anti-bot picture, see our [anti-bot bypass guide](https://scrapfly.io/blog/posts/how-to-bypass-anti-bot-protection-when-web-scraping).

With blocking handled, you can run the parsers from the previous sections at full scale.

## Scaling Homegate.ch Scraping with Scrapfly



ScrapFly's [Web Scraping API](https://scrapfly.io/web-scraping-api) is a single HTTP endpoint for collecting web data at scale, with a **99.99% success rate** across **130M+ proxies in 120+ countries**.

- [Anti-Scraping Protection bypass](https://scrapfly.io/docs/scrape-api/anti-scraping-protection) - automatically defeats Cloudflare, DataDome, PerimeterX, Akamai, and 90+ other bot systems.
- [Smart proxy rotation](https://scrapfly.io/docs/scrape-api/proxy) - residential and datacenter pools with country and ASN level geo-targeting.
- [JavaScript rendering](https://scrapfly.io/docs/scrape-api/javascript-rendering) - render SPAs and dynamic pages through real cloud browsers.
- [Browser automation scenarios](https://scrapfly.io/docs/scrape-api/javascript-scenario) - scroll, click, fill forms, and wait for elements without managing a browser fleet.
- [Format conversion](https://scrapfly.io/docs/scrape-api/getting-started#api_param_format) - return pages as HTML, JSON, clean text, or LLM ready Markdown.
- [Session management](https://scrapfly.io/docs/scrape-api/session) - keep cookies, headers, and IPs consistent across multi step flows.
- [Smart caching](https://scrapfly.io/docs/scrape-api/getting-started#api_param_cache) - cache successful responses to cut cost on repeat scraping jobs.
- [Python](https://scrapfly.io/docs/sdk/python), [TypeScript](https://scrapfly.io/docs/sdk/typescript), [Scrapy](https://scrapfly.io/docs/sdk/scrapy), and [no-code integrations](https://scrapfly.io/docs/integration/getting-started) including Make, n8n, Zapier, LangChain, and LlamaIndex.



### Web Scraping API

Scrape any website with our powerful API. Anti-bot bypass, JavaScript rendering, and rotating proxies built-in.



[Try Web Scraping API](https://scrapfly.io/docs/scrape-api/getting-started)



## FAQ

Does Homegate.ch have a public API?No, Homegate.ch doesn't offer a public API. The structured JSON embedded in the page source (Pinia state on property pages and `__INITIAL_STATE__` on search pages) is the practical source of truth for scrapers.







Why does my Homegate.ch scraper return empty data or 403 errors?Homegate.ch requires JavaScript rendering. Plain HTTP requests return 403 Forbidden or an empty HTML shell with no listing data. Use a headless browser or a scraping API with `render_js=True`, and make sure your User-Agent string matches a current Chrome release (131+).







What changed in Homegate's frontend migration?Homegate migrated property pages from a generic `__INITIAL_STATE__` store to `__PINIA_INITIAL_STATE__` (Vue 3 / Pinia) in 2025. Search pages still use the original `__INITIAL_STATE__` variable. If your older scraper stopped returning data on property pages, the Pinia migration is the cause. Switch the XPath to target `__PINIA_INITIAL_STATE__` and the data comes back.







Can I scrape other Swiss real estate platforms with this approach?Yes. Platforms like [ImmoScout24.ch](https://scrapfly.io/blog/posts/how-to-scrape-immoscout24-ch-real-estate-property-data) use similar hidden JSON data structures in script tags. Find the state script tag, extract the JSON, and parse the listings object. The XPath and regex patterns from this guide apply directly.







Is it legal to scrape Homegate.ch?Scraping publicly listed property data for research and analysis is generally permitted under Swiss law. Homegate.ch's Terms of Service restrict automated data collection, so review them before running a production scraper. Avoid storing personal data about private individuals to stay within GDPR bounds, and respect the site's `robots.txt` and rate limits.









## Summary

Homegate.ch stores its listing data in two different hidden state variables. Property pages use `window.__PINIA_INITIAL_STATE__` (Vue 3 / Pinia) since the 2025 frontend migration, and search pages still use `window.__INITIAL_STATE__`. Both parse cleanly with Python's `re` and `json` modules once you find the right script tag with XPath.

The JavaScript rendering requirement is the main hurdle. Homegate blocks plain HTTP requests regardless of parsing quality. Use a headless browser or a scraping API with `render_js=True`. Pair that with a Swiss IP (`country="CH"`) and a current Chrome User-Agent and the pages come through with the full script tags intact.

For production runs across hundreds of listings, the Scrapfly SDK drops the `asp`, `country`, and `render_js` flags into `BASE_CONFIG`. The Pinia and INITIAL\_STATE parsing functions from this guide work without modification.



Legal Disclaimer and PrecautionsThis tutorial covers popular web scraping techniques for education. Interacting with public servers requires diligence and respect:

- Do not scrape at rates that could damage the website.
- Do not scrape data that's not available publicly.
- Do not store PII of EU citizens protected by GDPR.
- Do not repurpose *entire* public datasets which can be illegal in some countries.

Scrapfly does not offer legal advice but these are good general rules to follow. For more you should consult a lawyer.

 

   Table of Contents















 

  Table of Contents- [Key Takeaways](#key-takeaways)
- [Why Scrape Homegate.ch?](#why-scrape-homegate-ch)
- [Project Setup](#project-setup)
- [How to Scrape Homegate.ch Property Pages?](#how-to-scrape-homegate-ch-property-pages)
- [Locating Property Data in the Pinia State](#locating-property-data-in-the-pinia-state)
- [Parsing the Pinia JSON with Python](#parsing-the-pinia-json-with-python)
- [How to Scrape Homegate.ch Search Pages?](#how-to-scrape-homegate-ch-search-pages)
- [Understanding Homegate.ch Search URL Structure](#understanding-homegate-ch-search-url-structure)
- [How Does Homegate.ch Search Pagination Work?](#how-does-homegate-ch-search-pagination-work)
- [How to Avoid Homegate.ch Web Scraping Blocking?](#how-to-avoid-homegate-ch-web-scraping-blocking)
- [Scaling Homegate.ch Scraping with Scrapfly](#scaling-homegate-ch-scraping-with-scrapfly)
- [FAQ](#faq)
- [Summary](#summary)
 
    Join the Newsletter  Get monthly web scraping insights 

 

  



Scale Your Web Scraping

Anti-bot bypass, browser rendering, and rotating proxies, all in one API. Start with 1,000 free credits.

  No credit card required  1,000 free API credits  Anti-bot bypass included 

 [Start Free](https://scrapfly.io/register) [View Docs](https://scrapfly.io/docs/onboarding) 

 Not ready? Get our newsletter instead. 

 

## Explore this Article with AI

 [ ChatGPT ](https://chat.openai.com/?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-homegate-ch-real-estate-property-data) [ Gemini ](https://www.google.com/search?udm=50&aep=11&q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-homegate-ch-real-estate-property-data) [ Grok ](https://x.com/i/grok?text=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-homegate-ch-real-estate-property-data) [ Perplexity ](https://www.perplexity.ai/search/new?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-homegate-ch-real-estate-property-data) [ Claude ](https://claude.ai/new?q=Summarize%20this%20page%3A%20https%3A%2F%2Fscrapfly.io%2Fblog%2Fposts%2Fhow-to-scrape-homegate-ch-real-estate-property-data) 



 ## Related Articles

 [  

 python scrapeguide 

### How to Scrape Real Estate Property Data using Python

Introduction to scraping real estate property data. What is it, why and how to scrape it? We'll also list dozens of popu...

 

 ](https://scrapfly.io/blog/posts/how-to-scrape-real-estate-property-data-using-python) [  

 python scrapeguide 

### How to Scrape Google Search Results in 2026

In this scrape guide we'll be taking a look at how to scrape Google Search - the biggest index of public web. We'll cov...

 

 ](https://scrapfly.io/blog/posts/how-to-scrape-google) [  

 python scrapeguide 

### How to Scrape Immowelt.de Real Estate Data

Immowelt.de is a major real estate website in Germany and it's suprisingly easy to scrape. In this tutorial, we'll be us...

 

 ](https://scrapfly.io/blog/posts/how-to-scrape-immowelt-de-real-estate-properties) 

  



   



 Scale your web scraping effortlessly, **1,000 free credits** [Start Free](https://scrapfly.io/register)