@NaoSaitoShinshu

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Seleniumで全要素が読み込まれるまで待機しても毎回結果が変わってしまう

解決したいこと

PythonとSelenium、BeautifulSoupを使用して、
あるSNSのプロフィールページに遷移→プロフィール内に記載されている各SNSのURLを取得→googleスプレッドシートに出力するという機能を作っています。

1.WebDriverで全要素が読み込まれるまで待機する処理を入れているのですが、毎回結果が違ってしまいます。
2.遷移元SNSでの最終投稿日を取得したいのですが、〇days agoのような表記がされている場合に、変数に値が入ってこず、値が取得できません。

該当するソースコード

Pyython(Google Colab)
i = 0
for row in df.itertuples():

  # D列が空欄ならURLから情報を取得 
  if row.名前 == "" :
    url = row.URL

    # ページの読み込みを完了まで最大15秒待機
    try:
        driver.get(url)
        WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located)

    except TimeoutException:
        print("タイムアウトが発生しました。")
    
    html = driver.page_source.encode('utf-8')
    soup = BeautifulSoup(html, 'html.parser')

    # 名前を取得
    user_name = soup.find('div', class_=lambda x: x and 'username' in x)

    if(user_name == None) :
      df.at[i, '名前'] = ''
    else :
      df.at[i, '名前'] = user_name.get_text()

    a_tags = []
    profile_element = soup.find('p', class_=lambda x: x and 'profile' in x)

    if (profile_element != None): 
        a_tags = profile_element.find_all('a')

        # URLを一括取得
        if(a_tags != None) :
          for a_tag in a_tags:
            href = a_tag.get('href')

            if(href != None) :

              # urlにtwitter.comが含まれていたらDFに値を追加
              if('twitter.com' in href) :
                df.at[i, 'Twitter'] = href

              # urlにinstagram.comが含まれていたらDFに値を追加
              elif('instagram.com' in href) :
                df.at[i, 'Instagram'] = href

              # urlにtiktok.comが含まれていたらDFに値を追加
              elif('tiktok.com' in href) :
                df.at[i, 'TikTok'] = href

              # urlにyoutube.comが含まれていたらDFに値を追加
              elif('youtube.com' in href) :
                df.at[i, 'YouTube'] = href

              # urlにその他のURLが含まれていたらDFに値を追加
              else :
                df.at[i, 'その他URL'] = href

    # 最終投稿日を取得
    latest_post = soup.find('span',class_=lambda x: x and 'CreatedAt' in x)

    if(latest_post == None) :
      latest_post = ""
    else :
      latest_post = latest_post.get_text()

    df.at[i, '最終投稿日'] = latest_post

自分で試したこと

いろいろ調べましたが情報が出てこず、手詰まりの状態です。
解決方法が分かる方がいらっしゃいましたら、助けていただけると幸いです。
よろしくお願いいたします。

0 likes

3Answer

取得対象のサイトが最終投稿日を教えてくれないなら、知る方法はないと思います。
Web-APIを利用すれば取得できる場合もあるでしょうが、x.comのように有料なところもありますね。

一日程度の誤差は許せるなら

  1. "CreatedAt"が見つかればそこから日付を抽出
  2. "CreatedAt"がなければ"days ago"を探し、見つかれば現在の日付からその日数を引いた日付を更新日とする

余談ですが、こういった表記は何の告知もなく変わることがあるし、今はほぼ同じ形でもサイトによって違っていることもありふれているため、必要な情報の抽出処理は共通化せずにサイトごとに個別で書いておいた方がいいかもしれません。
("CreatedAt 日付"のようなよく出てくる形は関数定義してそれを利用する形にするとか)

1Like

PythonとSelenium、BeautifulSoupを使用して、
あるSNSのプロフィールページに遷移→プロフィール内に記載されている各SNSのURLを取得→googleスプレッドシートに出力するという機能を作っています。

例えばInstagramはスクレイピング等は利用規約で禁止していますが、上記行為はそれには当たらないということでよろしいでしょうか?

0Like

Comments

  1. InstagramはURLを取得する各SNSのなかのひとつなのですが、これも禁止行為に当たるのでしょうか?
    Instagramのプロフィールから他SNSのURLを取得しているのではないです!

  2. 利用されるサービスの利用規約に従っていれば問題ないかと思います。(Instagramについては一例として挙げただけです)

  3. そもそもInstagramの利用規約を直接自分で読んで何がダメなのか確認しないと始まらない話だと思うのですが

    これも禁止行為に当たるのでしょうか?
    Instagramのプロフィールから他SNSのURLを取得しているのではないです!

    読みました?

    Instagram 利用規約

  4. 遷移元のSNSの利用規約は読みましたが、URLを取得する各SNSの規約は読んでいないです。

  5. すみません勘違いしてました。:bow_tone1:
    取得元は「あるSNS」で、「instagram.com」や「youtube.com」はそのSNS内のプロフィールの項目にすぎないのですね。

    "CreatedAt"もそのSNSの項目なので「サイトごとの個別対応」は不要で、そのSNSの方で各サービスの最終投稿日を取得しているわけですか。
    それならば"days ago"表記の場合もそのSNS側では最終更新日を持っているだろうから、そのSNSがweb APIを提供してくれているなら更新日も取得できる可能性が高そうですね。

  6. 大丈夫です、ありがとうございます!

    最終投稿日は「あるSNS」での投稿日を取得したいのですが、どうにも読み込みができていないようで、待機する処理を入れてみてもなかなかうまくいかず・・・
    〇days ago という文字列自体も変数に入ってこないのでどうしたものかと思っております…
    2013/7/21とかだったら取れるのですが…謎です。

そのSNSのHTMLをみてIDとかセレクタで直接取ればいいんじゃないですか

0Like

Your answer might help someone💌