Селен (python) падает при очистке многих страниц (50+) - PullRequest
2 голосов
/ 27 апреля 2020

У меня есть следующий скрипт (ниже), чтобы очистить данные связи от TRACE (ссылка в коде). Это модифицированная версия этого: https://github.com/treatmesubj/FINRABondScrape.

Он работает для 50-100 страниц, но не удается, когда я пытаюсь очистить все ~ 7600 страниц. Сценарий завершается с ошибкой: bond = [tablerow.text] и выдает следующую ошибку:

"StaleElementReferenceException: Message: ссылка на элемент устарела; либо элемент больше не присоединен к DOM, он отсутствует в текущем фрейм контекста или документ был обновлен "

Я добавил явное ожидание около tablerows, думая, что некоторые таблицы загружаются дольше, но, похоже, это не помогает, поскольку проблема остается. Я пробовал несколько других вещей, но у меня нет идей.

Любые мысли о том, как я могу это исправить, были бы полезны. Кроме того, любые советы по ускорению кода приветствуются. Спасибо!

Обновление: приведенное ниже предложение от KunduK + увеличение time.sleep(0.8) до time.sleep(1.5) в for l oop, похоже, исправило проблему. Но я подожду немного, прежде чем принять ответ от KunduK, если кто-то еще придумает лучший ответ.

# TRACE Bond Scraper
import os
import time
import numpy as np
import pandas as pd
from datetime import date
from datetime import datetime as dt
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.firefox.options import Options

options = Options()
options.headless = False
driver = webdriver.Firefox(options = options)
driver.get('http://finra-markets.morningstar.com/BondCenter/Results.jsp')

# Click agree, edit search and submit 
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, ".button_blue.agree"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, 'a.qs-ui-btn.blue'))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, 'a.ms-display-switcher.hide'))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, 'input.button_blue[type=submit]'))).click()
WebDriverWait(driver, 10).until(EC.presence_of_element_located(
    (By.CSS_SELECTOR, '.rtq-grid-row.rtq-grid-rzrow .rtq-grid-cell-ctn')))
headers = [title.text for title in driver.find_elements_by_css_selector(
    '.rtq-grid-row.rtq-grid-rzrow .rtq-grid-cell-ctn')[1:]]

# Find out the total number of pages to scrape
pg_no = WebDriverWait(driver, 10).until(EC.presence_of_element_located(
            (By.CSS_SELECTOR, '.qs-pageutil-total > span:nth-child(1)'))).text
pg_no = int(pg_no)

# Scrape tables
bonds = []
for page in range(1, pg_no):
    WebDriverWait(driver, 10).until(EC.presence_of_element_located(
        (By.CSS_SELECTOR, (f"a.qs-pageutil-btn.on[value='{str(page)}']"))))
    time.sleep(0.8)
    tablerows = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located(
        (By.CSS_SELECTOR, 'div.rtq-grid-bd > div.rtq-grid-row')))
    for tablerow in tablerows:
        bond = [tablerow.text]
        bonds.append(bond)
    WebDriverWait(driver, 10).until(EC.presence_of_element_located(
        (By.CSS_SELECTOR, ('a.qs-pageutil-next')))).click()

1 Ответ

1 голос
/ 27 апреля 2020

Измените эту строку с

WebDriverWait(driver, 10).until(EC.presence_of_element_located(
        (By.CSS_SELECTOR, (f"a.qs-pageutil-btn.on[value='{str(page)}']"))))

Это удалит класс on

WebDriverWait(driver, 10).until(EC.presence_of_element_located(
        (By.CSS_SELECTOR, (f"a.qs-pageutil-btn[value='{str(page)}']"))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...