【问题标题】:Selenium doesn't scrape tweet idsSelenium 不会抓取推文 ID
【发布时间】:2020-02-15 00:02:17
【问题描述】:

想象一下,你在这个 twitter 页面中,你必须获取它的所有 id! https://twitter.com/search?l=fr&q=%23metoo%20since%3A2017-11-06%20until%3A2017-11-09&src=typd

我正在使用 selenium 向下滚动,直到没有剩余,然后将所有 id 保存在一个列表中。

恐怕我的 for 循环并没有保存它们,我做错了什么?

twitter_ids_filename = 'all_ids.json'
id_selector = '.time a.tweet-timestamp'
tweet_selector = 'li.js-stream-item'
ids = []

for day in range(days):
    d1 = format_day(increment_day(start, 0))
    d2 = format_day(increment_day(start, 1))
    url = form_url(d1, d2)
    print(url)
    print(d1)
    driver.get(url)
    sleep(delay)

try:
    found_tweets = driver.find_elements_by_css_selector(tweet_selector)
    increment = 10

    while len(found_tweets) >= increment:
        print('scrolling down to load more tweets')
        driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
        sleep(delay)
        found_tweets = driver.find_elements_by_css_selector(tweet_selector)
        increment += 10

    print('{} tweets found, {} total'.format(len(found_tweets), len(ids)))

    for tweet in found_tweets:
        try:
            id = tweet.find_element_by_css_selector(id_selector).get_attribute('href').split('/')[-1]
            ids.append(id)
        except StaleElementReferenceException as e:
            print('lost element reference', tweet)

except NoSuchElementException:
    print('no tweets on this day')

【问题讨论】:

  • 你为什么不简单地刮一下data-tweed-id? (这里没有太多关于硒的内容,抱歉)
  • 我当然可以试试,你能给我举个小例子吗?
  • 你是说我应该用漂亮的汤吗?
  • 不 - 我正在查看您链接的页面,按 F12,看到适合您的选择器的 <li ..>,然后我在 <li ...> 中看到 <div ...> .. <div ...>有一类js-stream-tweet 和很多属性。属性之一是data-tweed-id="....."。刮掉它,你就是金子?
  • 还 ... 使用 ids.append(id.copy()) 只是为了确保您获得一份副本,而不是对您从拆分中获取的一个元素的引用。

标签: python selenium twitter


【解决方案1】:

我认为您的问题是选择器 li.js-stream-item 有点过于宽泛,并且包含不需要的元素。这是我在按js-stream-item 类选择时得到的结果:

如您所见,第一个元素不会包含您要查找的任何hrefs。通过限制过滤器来解决这个问题:

tweet_selector = 'li.js-stream-item:not(.AdaptiveStreamUserGallery)'

如果我尝试一下,我会用你的代码在每条找到的推文中得到一个 id:

scrolling down to load more tweets
23 tweets found, 0 total
INFO:root:    found 23 ids
INFO:root:    next id: 928321203617583104
INFO:root:    next id: 928317626031407104
INFO:root:    next id: 928268761890803712
INFO:root:    next id: 928262618195873793
INFO:root:    next id: 928239024682172416
INFO:root:    next id: 928220156123385856
INFO:root:    next id: 928191036681261057
INFO:root:    next id: 927958439153881088
INFO:root:    next id: 927957292418465793
INFO:root:    next id: 927898097203761153
INFO:root:    next id: 927804540031782912
INFO:root:    next id: 927799255699476481
INFO:root:    next id: 927779606429609984
INFO:root:    next id: 927648294016339970
INFO:root:    next id: 927590257297682432
INFO:root:    next id: 927536130827964416
INFO:root:    next id: 927523922534428672
INFO:root:    next id: 927521799063130113
INFO:root:    next id: 927331391091740672
INFO:root:    next id: 927330842304753664
INFO:root:    next id: 927330365982892033
INFO:root:    next id: 927325770925604865
INFO:root:    next id: 927324960175067137

另一个提示:您的代码将始终只收集最后一个n(其中n?q=%n 相同)推文,因为您总是覆盖循环中的found_tweets 列表。您必须汇总它们:

found_tweets = driver.find_elements_by_css_selector(tweet_selector)
all_tweets = found_tweets[:]
increment = 0

while len(found_tweets) >= increment:
    print('scrolling down to load more tweets')
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    time.sleep(delay)
    found_tweets = driver.find_elements_by_css_selector(tweet_selector)
    all_tweets += found_tweets[:]

    print('{} tweets found, {} total'.format(len(found_tweets), len(ids)))
    increment += 10


for tweet in all_tweets:
    try:
        id = tweet.find_element_by_css_selector(id_selector).get_attribute('href').split('/')[-1]
        ids.append(id)
    except StaleElementReferenceException as e:
        print('lost element reference', tweet)

print(ids)

【讨论】:

  • 您先生,是我的英雄。我现在看到我不擅长刮擦。你能给我推荐一些好的指南吗?
  • @blacksatius 不要自暴自弃,这些错误很少很明显并且很容易发现。至于导游,对不起,什么都别想!继续做你正在做的事情,你很快就会变得更好。
  • 好吧,我非常抱歉,但我有问题。 next_tweets_chunk = driver.find_elements_by_css_selector(tweet_selector) found_tweets += next_tweets_chunk[:] 打破循环,如果我不添加它,我找不到任何 ID
  • @blacksatius 对不起,我的错 - 我用我使用的完整代码示例更新了答案。
猜你喜欢
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多