2016-06-02 7 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) 

スニペットだけど、それはそれは罰金続けるだろう働いているときので、重要な部分だこと。

しかし、何かが停止すると、スレッドの1つがコンソールに「スクラップ:リンク」を送信しますが、コンソールには「要求するリンク:リンク」は送信されません。

これは、実際にウェブドライバを設定するときにスレッドが停止していることを意味します。私が見た限りでは、これはスレッドセーフであり、私はlock.aquireを使用して、ランダムな.exeを20のバッチから同じ結果を得て試してみました。

時々、スレッドは完全に動作し、要求を行うことができなくてもどこでも停止します。

アップデート:私は、コンソールを閉じると

は、時にはそれがsocket.errorががあった私に語りました。

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

しかし、私は物理的にコンソールを閉じるまで、それは喜んで何も言っていない時間のためにそこに座ってよ:あなたはその抜粋で試してみるの開始を見ることができますが、私は最後にこれを持っています。それから、socket.errorがポップアップし、死んだスレッドの "scraping:link"というメッセージが表示されます。

whileが始まる前に実際に失敗していることを実際に示唆していますが、そのスレッドの開始時にtrryは0に設定され、他の場所では参照されません。それに加えて、セレンのwebdriverを持っていなければsocket.errorもないので、以前のメッセージもブロックする必要があります。

更新#2:

それはまったく同じコードの単一のスレッドを実行するときに時間のために実行して幸せだように見えます。

しかし、スレッドロックでは違いはありませんでした。

リトルスタンプ。スレッドの代わりにサブプロセスを試して、それが何をしているのか見てみましょう。

更新#3:

スレッディングは長く安定していないですが、サブプロセスです。 OK Python。

答えて

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インスタンスを作成する方法を試してください)。 –

関連する問題