@shiorimizu

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

webdriverで取得されるpage_sourceが本来のページのものと明らかに異なる

解決したいこと

webdriverで取得されるpage_source(プログラム側のデータ)が本来ページのものと
明らかに異なる

例)
Pythonを用いてインスタグラムのスクレイピングを行っております。
スクレイピング対象のページにおいて特定の要素(ハッシュタグ)を取得したいと
考えているのですが、Chrome側で表示されるソースコード内の対象のクラス名を基に要素を
取得しようとすると、「NoSuchElementException」が発生してしまい、要素を見つけられないようです。
順序としては、インスタグラムにログインする処理を行った後スクレイピング対象のページへ
遷移してそこで要素を取得するといった感じになります。
そこで、プログラム側で正しく要素が読み込まれているのか疑問に思い、スクレイピング対象のページへ遷移し数秒経過したタイミングでdriver.page_sourceを確認するようなコードを試しに書いたところ、最初のhtmlタグはあるもののhtmlの終了タグがないことから何かしらの理由でプログラム側のページソースが欠損しており、そのため要素が見つけられないのではと考えました。
なお、page_sourceについてはprint文でコンソールに表示する形で確認を行いました。
このようにpage_sourceの要素が欠損してしまっている理由がわからずに困っております。
他にどのような検証をすればよいかなどのヒントをいただけますと幸いでございます。
よろしくお願いいたします。

発生している問題・エラー

要素の取得に関するエラー

NoSuchElementException
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div[@class="_a9zs"]"}

page_sourceを出力した時の先頭の内容

<html class="_9dls js-focus-visible _aa4d" (続く・・・)

末端の内容(ユーザ情報に関する箇所はxで伏せております)

content="xxxxx • Instagramの写真と動画" (←ここで終了)

htmlの終了タグで終わってないため不自然だと思いました。

該当するソースコード

(ユーザ情報に関する箇所はxで伏せております)

search_users.py

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep
# from helper import *
import sys
import os
from selenium.webdriver.common.by import By
# import chromeself.driver_binary
sys.path.append(os.path.join(os.path.dirname(__file__), '../'))
from helper import Env
import crowler.element_settings as es

INSTAGRAM_URL = "https://www.instagram.com"

class Instagram(object):
    def __init__(self):
        self.driver = webdriver.Chrome(ChromeDriverManager().install())
    
    def _login(self):
        self.driver.get(INSTAGRAM_URL)
        sleep(3)
        self.driver.find_element(By.XPATH, value='//input[@name="username"]').send_keys(Env.get("INSTAGRAM_USER_NAME"))
        self.driver.find_element(By.XPATH, value='//input[@name="password"]').send_keys(Env.get("INSTAGREAM_PASSWORD"))
        self.driver.find_element(By.XPATH, value='//button[@type="submit"]').submit()
        sleep(5)
    
    def execute_scraping(self):
        self._login()

        post_url = f"{INSTAGRAM_URL}/x/xx-xxxxxxxx"
        self.driver.get(post_url)
        sleep(3)

        #ここでpage_sourceを出力
        print(self.driver.page_source)
        #ここで要素を取得するとエラー(NoSuchElementException)が発生
        self.driver.find_element(By.XPATH, value=f'//div[@class="{es.div_post_frame}"]')

        #self.driver.find_element(By.XPATH, value=f'//div[@class="{es.div_post_content}"]')

if __name__ == '__main__':
    instagram = Instagram()
    instagram.execute_scraping()

自分で試したこと

page_sourceを出力するコードの前のsleepの時間をいくつかの間隔で延長してみたが結果は全く変化なし。
find_elementsで直接ハッシュタグに使われているaタグを読みに行くことも試みたが一つも要素を取得できなかった→このことから要素の欠損の可能性が濃厚ではと考えました。

0 likes

1Answer

複数のタグで開いているのでwindow_handlesで取得しましょう。

iframeは1ページに複数のフレームがあり、
windowも1ブラウザに複数のページがあります。見えているものと操作できるものは違う場合があります。

1Like

Your answer might help someone💌