Introduction
Cloudflare’s Captcha solutions are one of the biggest hurdles Python developers usually face while writing a web scraper. Cloudflare offers various solutions like bot detection, CAPTCHA challenges (including the newer Turnstile verification), and IP blocking to prevent automated website access for data retrieval. These protections often result in “Verify You Are Human” checks, 403 Forbidden errors, or the challenging 1020 Access Denied responses. In this post of the scraper series, we will learn about Cloudflare and its service that hinders web scraping and how you can use ScraperAPI’s APIs to bypass Cloudflare’s CAPTCHA/protection techniques.
Understanding Cloudflare Protection
What is Cloudflare?
- A global network service provider that offers website security, performance, and reliability solutions
- Acts as an intermediary between website visitors and hosting servers
- Provides protection against various cyber threats while improving website performance
- One of the world’s largest content delivery networks (CDNs)
Types of Cloudflare Protections
Captcha/Verify Human Checks
- Challenge-response tests that verify visitors are human and not automated bots
- Displays puzzles that are easy for humans but difficult for bots to solve
- Can be triggered when suspicious traffic patterns are detected
- Helps prevent spam, credential stuffing, and automated attacks.
- Cloudflare has also introduced Turnstile, a CAPTCHA alternative that aims to provide a better user experience and stronger privacy, while still effectively blocking unwanted bots.
DDoS Protection
- Defends against Distributed Denial of Service attacks that try to overwhelm websites
- Automatically detects and mitigates attack traffic without affecting legitimate users
- Uses Cloudflare’s massive network capacity to absorb attack traffic
- Provides always-on protection without requiring manual activation
Bot Detection
- Identifies and manages automated traffic to websites
- Uses machine learning to distinguish between good bots (search engines) and malicious bots
- Can block, challenge, or rate-limit suspicious bot activities
- Prevents credential stuffing, content scraping, and inventory hoarding
WAF (Web Application Firewall)
- Protects web applications from common vulnerabilities and attacks.
- Filters, monitors, and blocks malicious HTTP/HTTPS traffic.
- Defends against threats like SQL injection, cross-site scripting (XSS), and file inclusion exploits.
- Offers pre-configured rules and custom rule options to match specific security needs.
Usually, you see one of these screens on these sites where Cloudflare solutions are enabled. Before we dive in and implement a solution that bypasses Cloudflare’s captcha, aka verify you are a human thing, let’s find out the reasons behind it.
Why Cloudflare Shows Captcha Pages
Cloudflare shows CAPTCHA pages, also known as challenges, when it detects suspicious activity coming from your IP address or network (yes, it is quite possible that your ISP assigned you an IP from a range that has been performing activities on a website that are humanly not possible). Apart from accessing a webpage multiple times in a short span of time, other factors like not preparing a legitimate request (without a genuine User Agent and cookies), using the same IP to access hundreds of pages of the website, and accessing web pages that are rendered by JavaScript, aka Single Page Applications (SPAs), can also trigger these challenges. I have written in detail about writing unblockable scrapers in Python, which you can read here. ScraperAPI provides services like rotating proxies, JavaScript rendering, and location-based proxies that make your requests appear more legitimate.
Now, let’s see how we can leverage ScraperAPI’s APIs to access one of the websites
Development Setup
If you do not have an account with ScraperAPI, sign up here and create one. Once you are signed up and verified, you should be able to see a dashboard like the one below:
Since we are going to write a script in Python, you can either use the classic requests
library to access their service endpoint or the SDK they provide. I will prefer to use the requests library since it is pretty common, and you do not need any additional installation to access their service.
Now… we are going to try both kinds of screens/messages, usually one sees while accessing a Cloudflare-enabled website. Let’s deal with the one with a black screen having text: Verify you are a human. This may take a few seconds. And for that purpose, well, I am going to access the CloudFlare website itself.
Normally, when you access this link, you will see something like the above screenshot. Now, let me write a quick requests
based script to access this page. I took the cURL version of the request and converted it into the code below:
import requests if __name__ == '__main__': cookies = { 'cfz_facebook-pixel': '%7B%22OwdI_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.478667538%22%2C%22e%22%3A1776886289709%7D%2C%22VVgx_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.179686650%22%2C%22e%22%3A1776886289709%7D%2C%22bHox_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.2044183763%22%2C%22e%22%3A1776886289709%7D%2C%22elKW_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.2107283877%22%2C%22e%22%3A1776886289709%7D%7D', '_mkto_trk': 'id:713-XSC-918&token:_mch-cloudflare.com-9c88f5c3f640a670ee2c48ce593ba720', '_gcl_au': '1.1.1130581924.1745350290', 'AMCVS_8AD56F28618A50850A495FB6%40AdobeOrg': '1', '_biz_uid': 'e8324285efe04c1ff0fd9fca7bc252cc', '_ga': 'GA1.1.135522082.1745350291', '_biz_flagsA': '%7B%22Version%22%3A1%2C%22ViewThrough%22%3A%221%22%2C%22XDomain%22%3A%221%22%2C%22Mkto%22%3A%221%22%2C%22Ecid%22%3A%22-2025511809%22%7D', 'cfzs_amplitude': '%7B%22TTin_session_id%22%3A%7B%22v%22%3A%221745350291144%22%7D%7D', 's_sq': 'cloudflareinccloudflareincmktsite-prod%3D%2526c.%2526a.%2526activitymap.%2526page%253Dhttps%25253A%25252F%25252Fwww.cloudflare.com%25252Fcase-studies%25252F%2526link%253DMarlo%252520Beauty%252520-%252520Logo%2526region%253Dgatsby-focus-wrapper%2526.activitymap%2526.a%2526.c%2526pid%253Dhttps%25253A%25252F%25252Fwww.cloudflare.com%25252Fcase-studies%25252F%2526oid%253Dhttps%25253A%25252F%25252Fwww.cloudflare.com%25252Fcase-studies%25252Fmarlo-beauty%25252F%2526ot%253DA', 'cfz_reddit': '%7B%22fZaD_reddit_uuid%22%3A%7B%22v%22%3A%221745350326952.75bc4778-c6c5-4990-94cf-861af13f48eb%22%2C%22e%22%3A1776886326952%7D%7D', '_biz_nA': '7', '_biz_pendingA': '%5B%5D', 'cfzs_google-analytics_v4': '%7B%22nzcr_conversionCounter%22%3A%7B%22v%22%3A%223%22%7D%7D', 'cfz_amplitude': '%7B%22TTin_event_id%22%3A%7B%22v%22%3A%223%22%2C%22e%22%3A1776886328905%7D%2C%22TTin_device_id%22%3A%7B%22v%22%3A%227816f4ba-5829-4803-a764-bbce6ff7ed5f%22%2C%22e%22%3A1776886291144%7D%7D', 'cfz_google-analytics_v4': '%7B%22nzcr_engagementDuration%22%3A%7B%22v%22%3A%220%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_engagementStart%22%3A%7B%22v%22%3A%221745350328905%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_counter%22%3A%7B%22v%22%3A%222%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_ga4sid%22%3A%7B%22v%22%3A%22593233233%22%2C%22e%22%3A1745352128905%7D%2C%22nzcr_session_counter%22%3A%7B%22v%22%3A%221%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_ga4%22%3A%7B%22v%22%3A%22e369a8da-e6ff-4cf0-ae6d-d2404bb5c96a%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr__z_ga_audiences%22%3A%7B%22v%22%3A%22e369a8da-e6ff-4cf0-ae6d-d2404bb5c96a%22%2C%22e%22%3A1776886291144%7D%2C%22nzcr_let%22%3A%7B%22v%22%3A%221745350328905%22%2C%22e%22%3A1776886328905%7D%7D', '_uetvid': '64f53e901fb011f0a4daa93785096b12|1grodle|1745350330107|4|1|bat.bing.com/p/insights/c/b', 'OptanonConsent': 'isGpcEnabled=0&datestamp=Wed+Apr+23+2025+00%3A47%3A26+GMT%2B0500+(Pakistan+Standard+Time)&version=202503.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=f26ad77e-38cf-4ae3-aa72-028b6ed239f8&interactionCount=1&isAnonUser=1&landingPath=NotLandingPage&groups=C0001%3A1%2CC0003%3A1%2CC0002%3A1%2CC0004%3A1&AwaitingReconsent=false', '_cfuvid': 'YpQT3ogVCiX0mm8p9eeMMbbezNiYI0i5ar6acO6T1R4-1745482245165-0.0.1.1-604800000', 'recurring': 'true', 'AMCV_8AD56F28618A50850A495FB6%40AdobeOrg': '179643557%7CMCIDTS%7C20203%7CMCMID%7C66045687653907231282971490886219776815%7CMCAAMLH-1746087058%7C7%7CMCAAMB-1746087058%7CRKhpRz8krg2tLO6pguXWp5olkAcUniQYPHaMWWgdJ3xzPWQmdj0y%7CMCOPTOUT-1745489458s%7CNONE%7CvVersion%7C5.5.0', 'kndctr_8AD56F28618A50850A495FB6_AdobeOrg_identity': 'CiY2NjA0NTY4NzY1MzkwNzIzMTI4Mjk3MTQ5MDg4NjIxOTc3NjgxNVIRCOna7_flMhgBKgRJUkwxMAPwAf685rbmMg==', 'kndctr_8AD56F28618A50850A495FB6_AdobeOrg_cluster': 'va6', 'cf_clearance': '1bb.oUuZREkirX48HWfe77YXdBZHfi7HpFwbwjmqYv8-1745483858-1.2.1.1-KuP7xHDiRPxNcuwO4CvXrLMQ8SNBBaPfTmUsHKNeobAL4kQ8F6UoYJHyP7jRklmf1DilzY6UUaX4zTWeCxTOG1WZ8n0tW4fwTTfC8zWfQXXgxolw62k07cQJkVL6gkTomAlLlv0JjxwpPZx3ayR_ni_AGYoNMCHAcwIKimU0oJImwFVULKK5Q1Rhd_3ksHq1hEUkYM8JQMQ5vyTrzaIBiVaCFXQMUaRq52DnD8r0sgN3TzAQGFqO8q.2ZOXPOVFwdon7StJbFi8b_N37YnfLnXe1CZUmJh_pR_wz9Zrz4m9u_EYUh4XTN2F0bBtsR8A8SAF2Rsb858CjG4.ADXeE2dcvuIh6ZDkdaLoQF8ysjMI', 'OptanonConsent': 'isGpcEnabled=0&datestamp=Thu+Apr+24+2025+13%3A37%3A36+GMT%2B0500+(Pakistan+Standard+Time)&version=202309.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=f26ad77e-38cf-4ae3-aa72-028b6ed239f8&interactionCount=1&isAnonUser=1&landingPath=NotLandingPage&groups=C0001%3A1%2CC0003%3A1%2CC0002%3A1%2CC0004%3A1&AwaitingReconsent=false', '_forum_session': 'BLFpjzbhEL1yczD1UcC%2FWYN2488dcbrd4%2Bn7fKRCBTLYX3mNWq3NVKQKMmNsCMKg6%2FFNZEr4bBUujZEP4MWbEP6kxm1CP6UDicMinxn88zFhl8jmBirzQfmDpwuFNSuqNxhw0IflzvEG3Zu2YVMV91H4UW75XA2cwwIhWownjkmV%2F26XN3g%3D--R9T0GrQTTkTJ6szX--NPJRdu14VR1kcurUTlbtgg%3D%3D', '__cf_bm': 'cacJaeFCVraQt9PX12weAKhbUHFBzLeVAKDMAkQFPyk-1745484927-1.0.1.1-P0LMKVoz8BVdsc5eNFuuZzO4OvK0fJDrpvWJa679itzARp25wMwd_j4e1_GX1atv8rf9tHbr1NiMAy1nK643DulI_OI1jmD8ES1U1x5ZmMi9VIOQ0u6LzHQ8wNdsjRNZ', '_ga_SQCRB0TXZW': 'GS1.1.1745482258.2.1.1745484927.60.0.0', } headers = { 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'accept-language': 'en-US,en;q=0.9,ur;q=0.8,zh-CN;q=0.7,zh;q=0.6,ar;q=0.5', 'dnt': '1', 'priority': 'u=0, i', 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"', 'sec-ch-ua-arch': '"arm"', 'sec-ch-ua-bitness': '"64"', 'sec-ch-ua-full-version': '"134.0.6998.119"', 'sec-ch-ua-full-version-list': '"Chromium";v="134.0.6998.119", "Not:A-Brand";v="24.0.0.0", "Google Chrome";v="134.0.6998.119"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-model': '""', 'sec-ch-ua-platform': '"macOS"', 'sec-ch-ua-platform-version': '"15.3.2"', 'sec-fetch-dest': 'document', 'sec-fetch-mode': 'navigate', 'sec-fetch-site': 'none', 'sec-fetch-user': '?1', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36', # 'cookie': 'cfz_facebook-pixel=%7B%22OwdI_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.478667538%22%2C%22e%22%3A1776886289709%7D%2C%22VVgx_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.179686650%22%2C%22e%22%3A1776886289709%7D%2C%22bHox_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.2044183763%22%2C%22e%22%3A1776886289709%7D%2C%22elKW_fb-pixel%22%3A%7B%22v%22%3A%22fb.2.1745350289709.2107283877%22%2C%22e%22%3A1776886289709%7D%7D; _mkto_trk=id:713-XSC-918&token:_mch-cloudflare.com-9c88f5c3f640a670ee2c48ce593ba720; _gcl_au=1.1.1130581924.1745350290; AMCVS_8AD56F28618A50850A495FB6%40AdobeOrg=1; _biz_uid=e8324285efe04c1ff0fd9fca7bc252cc; _ga=GA1.1.135522082.1745350291; _biz_flagsA=%7B%22Version%22%3A1%2C%22ViewThrough%22%3A%221%22%2C%22XDomain%22%3A%221%22%2C%22Mkto%22%3A%221%22%2C%22Ecid%22%3A%22-2025511809%22%7D; cfzs_amplitude=%7B%22TTin_session_id%22%3A%7B%22v%22%3A%221745350291144%22%7D%7D; s_sq=cloudflareinccloudflareincmktsite-prod%3D%2526c.%2526a.%2526activitymap.%2526page%253Dhttps%25253A%25252F%25252Fwww.cloudflare.com%25252Fcase-studies%25252F%2526link%253DMarlo%252520Beauty%252520-%252520Logo%2526region%253Dgatsby-focus-wrapper%2526.activitymap%2526.a%2526.c%2526pid%253Dhttps%25253A%25252F%25252Fwww.cloudflare.com%25252Fcase-studies%25252F%2526oid%253Dhttps%25253A%25252F%25252Fwww.cloudflare.com%25252Fcase-studies%25252Fmarlo-beauty%25252F%2526ot%253DA; cfz_reddit=%7B%22fZaD_reddit_uuid%22%3A%7B%22v%22%3A%221745350326952.75bc4778-c6c5-4990-94cf-861af13f48eb%22%2C%22e%22%3A1776886326952%7D%7D; _biz_nA=7; _biz_pendingA=%5B%5D; cfzs_google-analytics_v4=%7B%22nzcr_conversionCounter%22%3A%7B%22v%22%3A%223%22%7D%7D; cfz_amplitude=%7B%22TTin_event_id%22%3A%7B%22v%22%3A%223%22%2C%22e%22%3A1776886328905%7D%2C%22TTin_device_id%22%3A%7B%22v%22%3A%227816f4ba-5829-4803-a764-bbce6ff7ed5f%22%2C%22e%22%3A1776886291144%7D%7D; cfz_google-analytics_v4=%7B%22nzcr_engagementDuration%22%3A%7B%22v%22%3A%220%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_engagementStart%22%3A%7B%22v%22%3A%221745350328905%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_counter%22%3A%7B%22v%22%3A%222%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_ga4sid%22%3A%7B%22v%22%3A%22593233233%22%2C%22e%22%3A1745352128905%7D%2C%22nzcr_session_counter%22%3A%7B%22v%22%3A%221%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr_ga4%22%3A%7B%22v%22%3A%22e369a8da-e6ff-4cf0-ae6d-d2404bb5c96a%22%2C%22e%22%3A1776886328905%7D%2C%22nzcr__z_ga_audiences%22%3A%7B%22v%22%3A%22e369a8da-e6ff-4cf0-ae6d-d2404bb5c96a%22%2C%22e%22%3A1776886291144%7D%2C%22nzcr_let%22%3A%7B%22v%22%3A%221745350328905%22%2C%22e%22%3A1776886328905%7D%7D; _uetvid=64f53e901fb011f0a4daa93785096b12|1grodle|1745350330107|4|1|bat.bing.com/p/insights/c/b; OptanonConsent=isGpcEnabled=0&datestamp=Wed+Apr+23+2025+00%3A47%3A26+GMT%2B0500+(Pakistan+Standard+Time)&version=202503.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=f26ad77e-38cf-4ae3-aa72-028b6ed239f8&interactionCount=1&isAnonUser=1&landingPath=NotLandingPage&groups=C0001%3A1%2CC0003%3A1%2CC0002%3A1%2CC0004%3A1&AwaitingReconsent=false; _cfuvid=YpQT3ogVCiX0mm8p9eeMMbbezNiYI0i5ar6acO6T1R4-1745482245165-0.0.1.1-604800000; recurring=true; AMCV_8AD56F28618A50850A495FB6%40AdobeOrg=179643557%7CMCIDTS%7C20203%7CMCMID%7C66045687653907231282971490886219776815%7CMCAAMLH-1746087058%7C7%7CMCAAMB-1746087058%7CRKhpRz8krg2tLO6pguXWp5olkAcUniQYPHaMWWgdJ3xzPWQmdj0y%7CMCOPTOUT-1745489458s%7CNONE%7CvVersion%7C5.5.0; kndctr_8AD56F28618A50850A495FB6_AdobeOrg_identity=CiY2NjA0NTY4NzY1MzkwNzIzMTI4Mjk3MTQ5MDg4NjIxOTc3NjgxNVIRCOna7_flMhgBKgRJUkwxMAPwAf685rbmMg==; kndctr_8AD56F28618A50850A495FB6_AdobeOrg_cluster=va6; cf_clearance=1bb.oUuZREkirX48HWfe77YXdBZHfi7HpFwbwjmqYv8-1745483858-1.2.1.1-KuP7xHDiRPxNcuwO4CvXrLMQ8SNBBaPfTmUsHKNeobAL4kQ8F6UoYJHyP7jRklmf1DilzY6UUaX4zTWeCxTOG1WZ8n0tW4fwTTfC8zWfQXXgxolw62k07cQJkVL6gkTomAlLlv0JjxwpPZx3ayR_ni_AGYoNMCHAcwIKimU0oJImwFVULKK5Q1Rhd_3ksHq1hEUkYM8JQMQ5vyTrzaIBiVaCFXQMUaRq52DnD8r0sgN3TzAQGFqO8q.2ZOXPOVFwdon7StJbFi8b_N37YnfLnXe1CZUmJh_pR_wz9Zrz4m9u_EYUh4XTN2F0bBtsR8A8SAF2Rsb858CjG4.ADXeE2dcvuIh6ZDkdaLoQF8ysjMI; OptanonConsent=isGpcEnabled=0&datestamp=Thu+Apr+24+2025+13%3A37%3A36+GMT%2B0500+(Pakistan+Standard+Time)&version=202309.1.0&browserGpcFlag=0&isIABGlobal=false&hosts=&consentId=f26ad77e-38cf-4ae3-aa72-028b6ed239f8&interactionCount=1&isAnonUser=1&landingPath=NotLandingPage&groups=C0001%3A1%2CC0003%3A1%2CC0002%3A1%2CC0004%3A1&AwaitingReconsent=false; _forum_session=BLFpjzbhEL1yczD1UcC%2FWYN2488dcbrd4%2Bn7fKRCBTLYX3mNWq3NVKQKMmNsCMKg6%2FFNZEr4bBUujZEP4MWbEP6kxm1CP6UDicMinxn88zFhl8jmBirzQfmDpwuFNSuqNxhw0IflzvEG3Zu2YVMV91H4UW75XA2cwwIhWownjkmV%2F26XN3g%3D--R9T0GrQTTkTJ6szX--NPJRdu14VR1kcurUTlbtgg%3D%3D; __cf_bm=cacJaeFCVraQt9PX12weAKhbUHFBzLeVAKDMAkQFPyk-1745484927-1.0.1.1-P0LMKVoz8BVdsc5eNFuuZzO4OvK0fJDrpvWJa679itzARp25wMwd_j4e1_GX1atv8rf9tHbr1NiMAy1nK643DulI_OI1jmD8ES1U1x5ZmMi9VIOQ0u6LzHQ8wNdsjRNZ; _ga_SQCRB0TXZW=GS1.1.1745482258.2.1.1745484927.60.0.0', } r = requests.get( 'https://community.cloudflare.com/t/scraperapi-using-cloudflare-to-attack-cloudflare-clients/470960', cookies=cookies, headers=headers, ) print(r.status_code)
When I run this code, it returns a 403 status code, which means Forbidden.
Chrome shows something like the below, as you can see, it shows the 403 status code.
Is the 403 status enough to figure out that the site is using Cloudflare? Not really. This is a generic status that any website can return as a response. So, what I am going to do is check whether the HTML of the page contains text like data-cf-beacon
or rayid
. These two indicators can help determine whether Cloudflare is being used. There’s another way to check as well. Any website that has Cloudflare configured typically returns certain headers, and one of them is CF-RAY
. You can check for the presence of this header too. Now let’s write a function that checks both the header and the text within the body of the page.
def detect_cf(response): body = response.text.strip().lower() headers = response.headers body_contains_cf = 'data-cf-beacon' in body and 'rayid' in body header_contains_cf = 'CF-RAY' in headers return body_contains_cf and header_contains_cf
Here, I am checking both headers and text within the body of the page. By using this function, you can figure out whether you need to use the ScraperAPI parameter to deal with Cloudflare or continue with the default features hence, helping you to save ScraperAPI credits.
Accessing ScraperAPI is pretty easy. All you have to do is make a call to their API endpoint with a payload that includes your API key.
def access_scraper_api(url): API_KEY = 'xxxx' payload = {'api_key': API_KEY, 'url': url} r = requests.get('https://api.scraperapi.com', params=payload) print(r.text)
Then, in the main function, you will call it like this:
url = "https://community.cloudflare.com/t/240-charged-without-consent-why-is-cloudflare-ignoring-so-many-refund-requests/790239" # url = "https://www.scrapingcourse.com/cloudflare-challenge" access_scraper_api(url)
You can also see the domain name, zus66gotoshemo.top, and other text there as well. You may also enable JS rendering and save the screenshot by adding the parameters render and screenshot, and setting them to True.
payload = {'api_key': API_KEY, 'url': url, 'render': True, 'screenshot': True, }
and access the screenshot URL from sa-screenshot
header value, in my case, it is here.
The usage of your credits will appear on the dashboard.
Conclusion
In this post, we learned how ScraperAPI makes it easier to access websites that are protected by Cloudflare. The same code I shared above can be used for both types of screens you saw earlier. ScraperAPI makes it easy to write scalable web scrapers that can scrape thousands of URLs without any issues.
Oh if you sign up here with my referral link or enter promo code adnan10, you will get a 10% discount on it. In case you do not get the discount then just let me know via email on my site and I’d sure help you out.
Looking to create something similar or even more exciting? Schedule a meeting or email me at kadnan @ gmail.com.
Love What You’re Learning Here?
If my posts have sparked ideas or saved you time, consider supporting my journey of learning and sharing. Even a small contribution helps me keep this blog alive and thriving.