> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenrows.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ZenRows® Universal Scraper API with Python: Getting Started

> Set up ZenRows Universal Scraper API with Python and Requests. Covers installation, API key configuration, and first scraping call.

Want to scrape the web effortlessly using Python? With ZenRows, you can handle complex scraping tasks, bypass anti-bot measures, and extract data from almost any website. This tutorial will guide you step-by-step in setting up a ZenRows scraper with Python.

## How to Use ZenRows with Python

Before we dive in, ensure you have Python 3 installed. If you're new to Python or web scraping, using an IDE such as <a href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener noreferrer nofollow">PyCharm</a> or <a href="https://code.visualstudio.com/docs/languages/python" target="_blank" rel="noopener noreferrer nofollow">Visual Studio Code</a> with the Python extension is recommended for a smoother experience.

We'll create a Python script named `scraper.py` inside a `/scraper` directory. If you need help setting up your environment, check out our [Python web scraping guide](https://www.zenrows.com/blog/web-scraping-python#setup) for detailed instructions on preparing everything.

### Install Python's requests Library

To interact with the ZenRows API, you can use Python's `requests` library. It's a widely used Python library for making HTTP requests, and it simplifies sending requests and handling responses, making it a great tool for integrating with web services like ZenRows.

This approach allows you to manage your API requests directly, allowing greater control over the web scraping process.

To install the `requests` library, use the following command in your terminal:

```bash theme={null}
pip install requests
```

This will install the library to send HTTP requests from your Python scripts.

### Make Your First Request

In this step, you will send your first request to ZenRows using the requests library to scrape content from a simple URL. We will use <a href="https://httpbin.io/get" target="_blank" rel="noopener noreferrer nofollow">HTTPBin.io/get</a> endpoint to see how ZenRows processes the request and returns the data.

Here's an example:

```python scraper.py theme={null}
# pip install requests
import requests

url = 'https://httpbin.io/get'
apikey = 'YOUR_ZENROWS_API_KEY'
params = {
    'url': url,
    'apikey': apikey,
}
response = requests.get('https://api.zenrows.com/v1/', params=params)
print(response.text)
```

Replace `YOUR_ZENROWS_API_KEY` with your actual API key and run the script:

```bash theme={null}
python scraper.py
```

It'll print something similar to this:

```json theme={null}
{
    "args": {},
    "headers": {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
        // additional headers omitted for brevity...
    },
    "origin": "38.154.5.224:6693",
    "url": "http://httpbin.io/get"
}
```

The response includes useful information, like the `origin`, which shows the IP address from which the request was made. ZenRows automatically rotates your IP address and changes the `User-Agent` for each request, helping to maintain anonymity and avoid blocks.

Perfect, you just learned how to make scraping requests with Python!

### Scrape More Complex Web Pages

While scraping simple sites like HTTPBin is straightforward, many websites, especially those with dynamic content or strict anti-scraping measures, require additional features. ZenRows allows you to bypass these defenses by enabling [JavaScript Rendering](/universal-scraper-api/features/js-rendering) and using [Premium Proxies](/universal-scraper-api/features/premium-proxy).

For example, if you try to scrape a page like <a href="https://www.g2.com/products/asana/reviews" target="_blank" rel="noopener noreferrer nofollow">G2's Asana reviews</a> without any extra configurations, you'll encounter an error:

```json theme={null}
{
    "code":"REQS002",
    "detail":"The requested URL domain needs JavaScript rendering and/or Premium Proxies due to its high-level security defenses. Please retry by adding 'js_render' and/or 'premium_proxy' parameters to your request.",
    "instance":"/v1",
    "status":400,
    "title":"Www.g2.com requires javascript rendering and premium proxies enabled (REQS002)",
    "type":"https://docs.zenrows.com/api-error-codes#REQS002"
}
```

This error happens because G2 employs advanced security measures that block basic scraping attempts.

Here's how you can modify the request to enable both:

```python scraper.py theme={null}
# pip install requests
import requests

url = 'https://www.g2.com/products/asana/reviews'
apikey = 'YOUR_ZENROWS_API_KEY'
params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'premium_proxy': 'true',
}
response = requests.get('https://api.zenrows.com/v1/', params=params)
print(response.text)
```

Run the script, and this time, ZenRows will handle the heavy lifting by rendering the page's JavaScript and routing your request through premium residential proxies. The response will contain the entire HTML content of the page:

```html theme={null}
<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <title>Asana Reviews 2024: Details, Pricing, & Features | G2</title>
    <!-- omitted for brevity -->
</head>
<body>
    <!-- page content -->
</body>
</html>
```

This demonstrates how you can scrape more advanced websites that rely on JavaScript or have stringent anti-bot mechanisms in place.

## Troubleshooting

Request failures can happen for various reasons. While some issues can be resolved by adjusting ZenRows parameters, others are beyond your control, such as the target server being temporarily down.

Below are some quick troubleshooting steps you can take:

<Steps>
  <Step title="Retry the Request">
    Network issues or temporary failures can cause your request to fail. Implementing retry logic can solve this by automatically repeating the request. Learn how to add retries in our [Python requests retry guide](https://www.zenrows.com/blog/python-requests-retry).

    Example of retry logic using requests:

    ```python scraper.py theme={null}
    import requests
    from requests.adapters import HTTPAdapter
    from urllib3.util.retry import Retry

    # Define the retry strategy
    retry_strategy = Retry(
        total=4,  # Maximum number of retries
        status_forcelist=[429, 500, 502, 503, 504],  # HTTP status codes to retry on
    )
    # Create an HTTP adapter with the retry strategy and mount it to session
    adapter = HTTPAdapter(max_retries=retry_strategy)

    # Create a new session object
    session = requests.Session()
    session.mount('http://', adapter)
    session.mount('https://', adapter)

    # Make a request using the session object
    response = session.get('https://scrapingcourse.com/ecommerce/')

    if response.status_code == 200:
        print(f'SUCCESS: {response.text}')
    else:
        print("FAILED")
    ```
  </Step>

  <Step title="Verify the Site is Accessible in Your Country">
    Sometimes, the target site might be region-restricted and only available to some proxies. ZenRows automatically selects the best proxy, but if the site is available only in specific regions, specify a geolocation using `proxy_country`.

    Here's how to choose a proxy in the US:

    ```python theme={null}
    params = {
        'premium_proxy': 'true',
        'proxy_country': 'us' # <- choose a premium proxy in the US
        # other configs...
    }
    response = client.get(url, params=params)
    ```

    If the target site requires access from a specific region, adding the `proxy_country` parameter will help.

    <Tip>Check out more about it on our [Geolocation Documentation Page](/universal-scraper-api/features/proxy-country).</Tip>
  </Step>

  <Step title="Check if the Site is Publicly Accessible">
    Some websites may require a session, so verifying if the site can be accessed without logging in is a good idea. Open the target page in an incognito browser to check this.

    You must handle session management in your requests if authentication credentials are required. You can learn how to scrape a website that requires authentication in our guide: [Web scraping with Python](https://www.zenrows.com/blog/web-scraping-login-python).
  </Step>

  <Step title="Get Help From ZenRows Experts">
    If the issue persists despite following these tips, our support team is available to assist you. Use the [Playground page](https://app.zenrows.com/Playground) or <a href="mailto:success@zenrows.com">contact us via email</a> to get personalized help from ZenRows experts.

    <Frame>
      <img src="https://static.zenrows.com/content/2_b67fbe5a87.png" style={{ borderRadius: '0.5rem' }} alt="ZenRows Request Playground Page" />
    </Frame>
  </Step>
</Steps>

## Frequently Asked Questions (FAQ)

<Accordion title="How can I bypass CloudFlare and other protections?">
  To successfully bypass CloudFlare or similar security mechanisms, you'll need to enable both `js_render` and `premium_proxy` in your requests. These features simulate a full browser environment and use high-quality residential proxies to avoid detection.

  You can also enhance your request by adding options like `wait` or `wait_for` to ensure the page fully loads before extracting data, improving accuracy.

  <Tip>Check out our documentation about the [wait](/universal-scraper-api/features/wait) and [wait\_for](/universal-scraper-api/features/wait-for) params</Tip>
</Accordion>

<Accordion title="How can I ensure my requests don't fail?">
  You can configure retry logic to handle failed HTTP requests. Learn more in our [guide on retrying requests](/zenrows-academy/retry-failed-requests).
</Accordion>

<Accordion title="How do I extract specific content from a page?">
  You can use the `css_extractor` parameter to directly extract content from a page using CSS selectors. Find out more in our [tutorial on data parsing](/zenrows-academy/how-to-extract-data).
</Accordion>

<Accordion title="Can I integrate ZenRows with Python's Requests and BeautifulSoup?">
  Yes! You can use ZenRows alongside Python Requests and BeautifulSoup for HTML parsing. Learn how in our guide on [Python Requests and BeautifulSoup integration](/zenrows-academy/how-to-extract-data#python-with-beautifulsoup).
</Accordion>

<Accordion title="How can I simulate user interactions on the target page?">
  Use the `js_render` and `js_instructions` features to simulate actions such as clicking buttons or filling out forms. Discover more about interacting with web pages in our [JavaScript instructions guide](/universal-scraper-api/features/js-instructions).
</Accordion>

<Accordion title="How can I scrape faster using ZenRows?">
  You can scrape multiple URLs simultaneously by making concurrent API calls. Check out our guide on [using concurrency](/universal-scraper-api/features/concurrency#using-concurrency) to boost your scraping speed.
</Accordion>
