Очистка динамических c твитов из твиттера с использованием Selenium - PullRequest
1 голос
/ 07 мая 2020

Это может выглядеть как повторяющийся вопрос, но поверьте мне, я заметил кое-что новое с твиттером.

Ранее я сделал скребок твиттера, который извлекает заданное количество твитов с помощью прокрутки и ожидания динамического c элементов. Но сейчас, похоже, это не работает. Он не очищает более 10 твитов. Кроме того, твиты, которые он очищает, - это только последние 10 твитов (из всех твитов, которые я загружаю изначально с помощью прокрутки)

Эта функция должна очищать как минимум n твитов. Вначале появляется около 10 твитов. Поэтому я прокручиваю страницу n/10-1 раз, чтобы загрузить все n твитов. Затем я очищаю все div с определенным именем класса.

def get_n_tweets(n, search_str='Covid 19'):
    driver = webdriver.Firefox(executable_path='geckodriver.exe')
    driver.get("http://twitter.com/search?q=" + search_str + "&src=typd")

    response = []
    for x in range(math.ceil(n / 10)-1):
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(5)
    try:
        WebDriverWait(driver, 20).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "div[class='css-1dbjc4n r-1iusvr4 r-16y2uox r-1777fci r-5f2r5o r-1mi0q7o']"))
        )

        e_tweets = driver.find_elements(By.CSS_SELECTOR, "div[class='css-1dbjc4n r-1iusvr4 r-16y2uox r-1777fci r-5f2r5o r-1mi0q7o']")

        for e_tweet in e_tweets:
            e_fullname = e_tweet.find_element(By.CSS_SELECTOR, "div>span[class='css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0']")
            e_tweet_text = e_tweet.find_element(By.CSS_SELECTOR, "div[class='css-901oao r-hkyrab r-1qd0xha r-a023e6 r-16dba41 r-ad9z0x r-bcqeeo r-bnwqim r-qvutc0']")
            response.append({'by': e_fullname.text,
                             'tweet': e_tweet_text.text,
                             'score': TextBlob(e_tweet_text.text).sentiment.polarity})            
    finally:
        driver.quit()
    return response

Что я пробовал? Я попытался загрузить столько твитов, сколько мне нужно, прокрутив страницу вниз, прокрутив назад до начала страницы, а затем получил необходимые элементы. Это вызывает ошибку StaleElementError.

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

Ищу простой и стандартный способ решения этой проблемы. Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 07 мая 2020

Я уже сталкивался с таким поведением на веб-сайтах раньше. Ваш лучший путь вперед - воспользоваться классами AbstractEventListener и EventFiringWebDriver .

Сначала вы должны реализовать класс TwitterListener и определить методы before_execute_script и after_execute_script для извлечения необходимой информации из твитов.

class TwitterListener(AbstractEventListener):

    def __init__(self):
        """Data structures to hold tweets goes here"""

    def before_execute_script(self, url, driver):
        """Scan DOM for tweets and scrape"""

    def after_execute_script(self, url, driver):
        """Scan DOM for new tweets and scrape"""

Затем использовать это TwitterListener, вы используете EventFiringWebDriver, в котором используются все ожидаемые вами методы, и код для выполнения скрипта будет выполняться автоматически!

from [separate file] import TwitterListener

driver = EventFiringWebDriver(executable_path='geckodriver.exe', TwitterListener())

Некоторые моменты, которые следует учитывать при таком подходе:

  1. Любая обработка данных, таких как ваш TextBlob().sentiment.polarity, должна происходить за пределами очистки твита l oop. Я бы рекомендовал использовать для этого какую-то форму многопроцессорности.

  2. Вы можете переместить любое поведение сна в класс TwitterListener, чтобы гарантировать, что вы не аннулируете элемент до того, как вы его очистили.

Надеюсь, это поможет!

...