2016-06-02 1 views
2

URL을 가져 와서 셀레늄에서 요청하고 데이터를 구문 분석하는 스레드가 있습니다.일부 스레드가 Webdriver를 생성 할 때 Python Selenium이 실패 함

대부분이 스레드는 정상적으로 작동합니다. 그러나 때로는 webdriver를 만드는 데 매달리는 것처럼 보이고 예외 처리를 할 수없는 것처럼 보입니다.

스레드의 시작 :

스 니펫이다 그러나 그것은 잘 계속할 것이다 일하고 때 때문에 중요한 부분
def GetLink(eachlink): 

    trry = 0 #10 Attempts at getting the data 

    while trry < 10: 

     print "Scraping: ", eachlink 
     try: 

      Numbergrab = [] 
      Namegrab = [] 
      Positiongrab = [] 

      nextproxy = (random.choice(ProxyList)) 
      nextuseragent = (random.choice(UseragentsList)) 
      proxywrite = '--proxy=',nextproxy 
      service_args = [ 
      proxywrite, 
      '--proxy-type=http', 
      '--ignore-ssl-errors=true', 
      ] 

      dcap = dict(DesiredCapabilities.PHANTOMJS) 
      dcap["phantomjs.page.settings.userAgent"] = (nextuseragent) 
      pDriver = webdriver.PhantomJS('C:\phantomjs.exe',desired_capabilities=dcap, service_args=service_args) 
      pDriver.set_window_size(1024, 768) # optional 
      pDriver.set_page_load_timeout(20) 

      print "Requesting link: ", eachlink 
      pDriver.get(eachlink) 
      try: 
       WebDriverWait(pDriver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@class='seat-setting']"))) 
      except: 
       time.sleep(10) 

.

하지만 뭔가가 스톨되면 스레드 중 하나가 콘솔에 "스크래핑 : 링크"를 보내고 콘솔에는 "요청 링크 : 링크"를 보내지 않습니다.

실제로 웹 드라이버를 설정할 때 스레드가 멈추고 있음을 의미합니다. 지금까지 본 적이 스레드 안전하고 lock.aquire 사용하여 동일한 결과 20 일괄 처리 중 임의의 .exe주고 시도했습니다.

때로는 스레드가 완벽하게 작동하여 요청하지 않아도 멈출 수 있습니다.

업데이트 : 콘솔을 닫을 때

때때로 그것은 socket.error가 있었다 나에게 말한다.

except: 
       trry +=1 
       e = sys.exc_info()[0] 
       print "Problem scraping link: ", e 

하지만 물리적으로 콘솔을 닫습니다 때까지 행복하게 아무 말없는 시간 동안 거기에 앉아 있습니다 : 당신은 그 조각의 시도의 시작을 볼 수 있습니다 나는 끝에이 있습니다. 그런 다음 socket.error 및 죽은 스레드에 대한 "스크래핑 : 링크"메시지를 표시합니다.

실제로 시작하기 전에 실패하고 있지만 해당 스레드가 시작할 때 0으로 설정되며 다른 곳에서는 참조되지 않습니다. 게다가 셀레늄 webdriver가 없으면 socket.error가 없으므로 이전 메시지도 차단해야합니다.

업데이트 # 2 : 그것은 동일한 코드의 단일 스레드를 실행할 때 시간 동안 실행하는 행복처럼

것 같습니다.

그러나 스레드 잠금은 차이를 만들지 않았습니다.

약간의 문제가 발생했습니다. 스레드 대신 하위 프로세스를 사용하여 수행되는 작업을 확인합니다.

업데이트 # 3 :

스레딩은 길지만 안정적이지는 않지만 하위 처리가 있습니다. OK 파이썬.

답변

2

Firefox, Chrome 또는 PhantomJS를 사용하는 경우 멀티 스레딩 및 멀티 프로세싱 모두에서이 문제가 발생했습니다. 어떤 이유로 든 브라우저를 인스턴스화하기위한 호출 (e.q. driver = webdriver.Chrome())은 반환하지 않습니다.

대부분의 스크립트는 비교적 짧은 기간 동안 스레드/프로세스가 거의 없으므로 문제가 자주 발생하지 않습니다. 그러나 몇 시간 동안 실행되어 수백 개의 브라우저 개체를 만들고 파괴 할 수있는 스크립트가 몇 개 있으며, 몇 번씩 실행을 경험할 수 있습니다.

(이 안된)

:

내 솔루션 자체의 기능/방법으로 브라우저 인스턴스를 넣어 한 후 많은 시간 제한 중 하나를 사용하여 기능/방법을 장식하고 PyPI에서 사용할 수 장식을 다시 시도하는 것입니다 이 S를 사용하기 때문에, 메인 쓰레드에서만 작동 timeoutcontext

from retrying import retry 
from selenium import webdriver 
from timeoutcontext import timeout, TimeoutException 


def retry_if_timeoutexception(exception): 
    return isinstance(exception, TimeoutException) 


@retry(retry_on_exception=retry_if_timeoutexception, stop_max_attempt_number=3) 
@timeout(30) # Allow the function 30 seconds to create and return the object 
def get_browser(): 
    return webdriver.Chrome() 

https://pypi.python.org/pypi/retrying

https://pypi.python.org/pypi/timeoutcontext

+0

ignal.alarm()과 Python은 주 스레드에만 전달되는 모든 신호를 시행합니다. 따라서 멀티 스레딩과 비 메인 스레드에서 webdriver를 호출하는 경우에는이 솔루션을 사용할 수 없습니다. 대신에 다중 처리를해야합니다 (또는 주 스레드가 모든 새로운 webdriver 인스턴스를 생성하는 몇 가지 방법을 사용하십시오). –

관련 문제