Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python + splinter + http: Error - httplib.ResponseNotReady

With splinter and Python, I have two threads running, each visiting the same main URL but different routes, e.g. thread one hits: mainurl.com/threadone and thread two hits: mainurl.com/threadtwo using:

from splinter import Browser
browser = Browser('chrome')

But came across the following error:

Traceback (most recent call last):
  File "multi_thread_practice.py", line 299, in <module>
    main()
  File "multi_thread_practice.py", line 290, in main
    first_method(r)
  File "multi_thread_practice.py", line 195, in parser
    second_method(title, name)
  File "multi_thread_practice.py", line 208, in confirm_product
    third_method(current_url)
  File "multi_thread_practice.py", line 214, in buy_product
    browser.visit(url)
  File "/Users/joshua/anaconda/lib/python2.7/site-packages/splinter/driver/webdriver/__init__.py", line 184, in visit
    self.driver.get(url)
  File "/Users/joshua/anaconda/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 261, in get
    self.execute(Command.GET, {'url': url})
  File "/Users/joshua/anaconda/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 247, in execute
    response = self.command_executor.execute(driver_command, params)
  File "/Users/joshua/anaconda/lib/python2.7/site-packages/selenium/webdriver/remote/remote_connection.py", line 464, in execute
    return self._request(command_info[0], url, body=data)
  File "/Users/joshua/anaconda/lib/python2.7/site-packages/selenium/webdriver/remote/remote_connection.py", line 488, in _request
    resp = self._conn.getresponse()
  File "/Users/joshua/anaconda/lib/python2.7/httplib.py", line 1108, in getresponse
    raise ResponseNotReady()
httplib.ResponseNotReady

What is the error and how should I go about handling the issue?

Thank you in advance and will be sure to upvote/accept answer

CODE ADDED

import time
from splinter import Browser
import threading

browser = Browser('chrome')

start_time = time.time()

urlOne = 'http://www.practiceurl.com/one'
urlTwo = 'http://www.practiceurl.com/two'
baseUrl = 'http://practiceurl.com'

browser.visit(baseUrl)

def secondThread(url):
    print 'STARTING 2ND REQUEST: ' + str(time.time() - start_time)
    browser.visit(url)
    print 'END 2ND REQUEST: ' + str(time.time() - start_time)


def mainThread(url):
    print 'STARTING 1ST REQUEST: ' + str(time.time() - start_time)
    browser.visit(url)
    print 'END 1ST REQUEST: ' + str(time.time() - start_time)


def main():
    threadObj = threading.Thread(target=secondThread, args=[urlTwo])
    threadObj.daemon = True

    threadObj.start()

    mainThread(urlOne)

main()
like image 213
Jo Ko Avatar asked Oct 17 '22 13:10

Jo Ko


1 Answers

As far as I can tell, what you're trying to do isn't possible on one browser. Splinter is acting on an actual browser, and as such, passing in many commands at the same time causes issues. It acts just as a human would interact with a browser (automated of course). It is possible to open many browser windows, but you cannot send requests in a different thread without receiving the response from the previous request. That causes a CannotSendRequest error. So, what I recommend (if you need to use threads) is open two browsers, and then use threads to send a request through each of them. Otherwise, it can't be done.

This thread is on selenium, but the information is transferrable. Selenium multiple tabs at once Again,this says what you want (I assume) to do is impossible. And the green ticked answer giver makes the same recommendation I do.

Hope that doesn't put you off track too much, and helps you out.

EDIT: Just to show:

import time
from splinter import Browser
import threading

browser = Browser('firefox')
browser2 = Browser('firefox')

start_time = time.time()

urlOne = 'http://www.practiceurl.com/one'
urlTwo = 'http://www.practiceurl.com/two'
baseUrl = 'http://practiceurl.com'

browser.visit(baseUrl)


def secondThread(url):
    print 'STARTING 2ND REQUEST: ' + str(time.time() - start_time)
    browser2.visit(url)
    print 'END 2ND REQUEST: ' + str(time.time() - start_time)


def mainThread(url):
    print 'STARTING 1ST REQUEST: ' + str(time.time() - start_time)
    browser.visit(url)
    print 'END 1ST REQUEST: ' + str(time.time() - start_time)


def main():
    threadObj = threading.Thread(target=secondThread, args=[urlTwo])
    threadObj.daemon = True

    threadObj.start()

    mainThread(urlOne)

main()

Note that I used firefox cause I've not got chromedriver installed.

It might be a good idea to set a wait after the browsers open, just to make sure they're fully ready, before the timers begin.

like image 185
Generic Snake Avatar answered Oct 21 '22 08:10

Generic Snake