【问题标题】:Scraping dynamic tweets from twitter using Selenium使用 Selenium 从 twitter 抓取动态推文
【发布时间】:2020-05-06 21:05:52
【问题描述】:

这可能看起来像一个重复的问题,但相信我,我在 twitter 上观察到了一些新的东西。

我之前制作了一个推特抓取工具,它使用滚动和等待动态元素来获取给定数量的推文。但它现在似乎不起作用。它不会抓取超过 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。

我怀疑这是造成这种情况的原因: 在网页中,当我向下滚动以加载指定数量的推文然后返回页面顶部时,我之前加载的推文消失了。

我正在寻找一种简单而标准的方法来解决这个问题。任何帮助将不胜感激!

【问题讨论】:

    标签: python-3.x selenium-webdriver web-scraping


    【解决方案1】:

    我以前在网站上处理过这种行为。您最好的前进方式是利用AbstractEventListenerEventFiringWebDriver 课程。

    您应该首先实现一个TwitterListener 类,并定义before_execute_scriptafter_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,都应该在推文抓取循环之外进行。我建议为此使用某种形式的多处理。

    2. 您可能希望将任何睡眠行为移至 TwitterListener 类,以确保在抓取元素之前不会使其无效。

    希望这会有所帮助!

    【讨论】:

    • 非常感谢!我不知道 AbstractEventListener 或 EventFiringWebDriver。我去查一下。
    • 我已经用我可以编写的代码更新了答案,该代码与您建议的代码最接近。虽然它并不完美,但当我无法摆脱 StaleElementError 时,它比以前好多了。
    猜你喜欢
    • 2022-01-16
    • 1970-01-01
    • 2022-12-22
    • 2019-09-29
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    相关资源
    最近更新 更多