Detecta de forma confiable la carga de la página o el tiempo de espera, Selenium 2

Estoy escribiendo un raspador web genérico utilizando Selenium 2 (versión 2.33 enlaces de Python, controlador de Firefox). Se supone que toma unarbitrario Haga URL, cargue la página e informe todos los enlaces salientes. Debido a que la URL es arbitraria, no puedo hacer ninguna suposición sobre el contenido de la página, por lo que el consejo habitual (esperar a que un elemento específico esté presente) es inaplicable.

Tengo el código que se supone que sondeodocument.readyState hasta que llegue a "completo" o haya transcurrido un tiempo de espera de 30 segundos, y luego proceda:

def readystate_complete(d):
    # AFAICT Selenium offers no better way to wait for the document to be loaded,
    # if one is in ignorance of its contents.
    return d.execute_script("return document.readyState") == "complete"

def load_page(driver, url):
    try:
        driver.get(url)
        WebDriverWait(driver, 30).until(readystate_complete)
    except WebDriverException:
        pass

    links = []
    try:
        for elt in driver.find_elements_by_xpath("//a[@href]"):
            try: links.append(elt.get_attribute("href"))
            except WebDriverException: pass
    except WebDriverException: pass
    return links

Este tipo de trabajos, pero en aproximadamente una página de cada cinco, el.until llamada cuelga para siempre. Cuando esto sucede, generalmente el navegador no ha terminado de cargar la página (el "zumbador" todavía está girando) pero pueden pasar decenas de minutos y el tiempo de espera no se activa. Pero a veces la página parece haberse cargado por completo y el script aún no continúa.

¿Lo que da? ¿Cómo puedo hacer que el tiempo de espera funcione de manera confiable? ¿Hay una mejor manera de solicitar una espera para cargar la página (si no se pueden hacer suposiciones sobre el contenido)?

Nota: La obsesiva captura e ignorancia deWebDriverException ha demostrado ser necesario para asegurar que extraiga tantos enlaces de la página como sea posible, ya sea que JavaScript dentro de la página esté haciendo cosas graciosas con el DOM (por ejemplo, solía obtener errores de "elemento obsoleto" en el bucle que extrae los atributos HREF ).

NOTA: Hay muchas variaciones en esta pregunta tanto en este sitio como en cualquier otro sitio, pero todas tienen una diferencia sutil pero crítica que hace que las respuestas (si las hay) sean inútiles para mí, o he intentado las sugerencias y no las he intentado. no funcionaPor favor contesteexactamente La pregunta que he hecho.

Respuestas a la pregunta(5)

Su respuesta a la pregunta