title: How does Cloudflare differentiate Selenium and Requests traffic?
body: <h1>Context</h1>
  
  <p>I am currently attempting to build a small-scale bot using Selenium and Requests module in Python.<br>
  However, the webpage I want to interact with is running behind Cloudflare.<br>
  My python script is running over Tor using stem module.<br>
  My traffic analysis is based on Firefox's "Developer options->Network" using Persist Logs.</p>
  
  <h1>My findings so far:</h1>
  
  <ul>
  <li>Selenium's Firefox webdriver can often access the webpage without going through "checking browser page" (return code 503) and "captcha page" (return code 403).</li>
  <li>Requests session object with the same user agent always results in "captcha page" (return code 403).</li>
  </ul>
  
  <p>If Cloudflare was checking my Javascript functionality, shouldn't my requests module return 503 ?</p>
  
  <h1>Code Example</h1>
  
  <pre><code>driver = webdriver.Firefox(firefox_profile=fp, options=fOptions)
  driver.get("https://www.cloudflare.com")   # usually returns code 200 without verifying the browser
  
  session = requests.Session()
  # ... applied socks5 proxy for both http and https ... #
  session.headers.update({"user-agent": driver.execute_script("return navigator.userAgent;")})
  page = session.get("https://www.cloudflare.com")
  print(page.status_code) # return code 403
  print(page.text)        # returns "captcha page"
  </code></pre>
  
  <p>Both Selenium and Requests modules are using the same user agent and ip.<br>
  Both are using GET without any parameters.<br>
  How does Cloudflare distinguish these traffic?<br>
  Am I missing something?</p>
  
  <hr>
  
  <p>I tried to transfer cookies from the webdriver to the requests session to see if a bypass is possible but had no luck.<br>
  Here is the used code:</p>
  
  <pre><code>for c in driver.get_cookies():
      session.cookies.set(c['name'], c['value'], domain=c['domain'])
  </code></pre>