PythonでSelenium Webdriverを使用してWebページをスクロールするにはどうすればよいですか?


131

私は現在、セレンWebドライバーを使用してFacebookのユーザーの友達ページを解析し、AJAXスクリプトからすべてのIDを抽出しています。しかし、すべての友達を取得するには、下にスクロールする必要があります。Seleniumで下にスクロールするにはどうすればよいですか。私はpythonを使用しています。



driver.execute_script(f "window.scrollTo(0、{2 ** 127});")
AturSams

回答:


263

使用できます

driver.execute_script("window.scrollTo(0, Y)") 

ここで、Yは高さです(フルモニターでは1080です)。(@lukeisに感謝)

あなたも使うことができます

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

ページの一番下までスクロールします。

ソーシャルネットワークやFacebookなど、無限に読み込まれるページにスクロールする場合(@Cuong Tranに感謝)

SCROLL_PAUSE_TIME = 0.5

# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # Wait to load page
    time.sleep(SCROLL_PAUSE_TIME)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

別の方法(Juanseに感謝)は、オブジェクトを選択して

label.sendKeys(Keys.PAGE_DOWN);

1
すばらしいです。について少し説明してもらえますscrollHeightか、それはどういう意味で、どのように機能しますか?
Jasonゴール

次に、変数「last_height」をどのように使用しますか?私のコードにも同様のものがあり、ブラウザが下にスクロールしています。ただし、データを見ると、スクレイピングしているのは、最初のページからデータをk回スクレイピングするだけです。 "k"は、ブラウザーが下にスクロールした回数です。
Peter Lenaers

72

無限のページlinkedin.comなど)の一番下までスクロールしたい場合は、次のコードを使用できます。

SCROLL_PAUSE_TIME = 0.5

# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # Wait to load page
    time.sleep(SCROLL_PAUSE_TIME)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

リファレンス:https : //stackoverflow.com/a/28928684/1316860


これは素晴らしい。Instagramでこれを使用しようとしている人は、まずActionChainsを使用して[もっと読み込む]ボタンにタブで移動し、次にCuong Tranのソリューションを適用する必要があるかもしれません...少なくともそれが私にとってうまくいきました。
Mwspencer

答えてくれてありがとう!私がやりたいことは、例えば、インスタグラムでページの一番下までスクロールして、ページのhtml全体をつかむことです。一番下までスクロールした後、入力としてlast_heightを指定してページ全体のhtmlを取得できる関数はセレンにありますか?
Swan87 2018

2
SCROLL_PAUSE_TIMEばらつくが、それは私のために約2秒かかります。
ssi-anik


21

ここに示すのと同じ方法:

Pythonではあなたが使うことができます

driver.execute_script("window.scrollTo(0, Y)")

(Yはスクロールする垂直位置です)


15
element=find_element_by_xpath("xpath of the li you are trying to access")

element.location_once_scrolled_into_view

これは、表示されていない「li」にアクセスしようとしたときに役立ちました。


'find_element_by_xpath'はドライバー関数または何であるか、 '。location_once_scrolled_into_view'はエラーを返しますNoSuchElementException:メッセージ:no such element:Unable to Locate element:{"method": "xpath"、 "selector": "// * [@ id = "timeline-medley"] / div / div [2] / div [1] "}
Walid Bousseta

あともう一つだけ。location_once_scrolled_into_viewなしで呼ばれるべき理由() はそれlocation_once_scrolled_into_viewがPython だからですproperty。ソースコードはこちら:selenium / webelement.py at d3b6ad006bd7dbee59f8539d81cee4f06bd81d64・SeleniumHQ / selenium
DataAlchemist

10

私の目的のために、ウィンドウの位置を考慮して、さらに下にスクロールしたかったのです。私の解決策は似ていて使用されましたwindow.scrollY

driver.execute_script("window.scrollTo(0, window.scrollY + 200)")

現在のyスクロール位置+ 200に移動します



7

その問題を解決するために私が見つけた最も簡単な方法は、ラベルを選択して送信することでした:

label.sendKeys(Keys.PAGE_DOWN);

うまくいきますように!


6

これらの回答はどれも私にはうまくいきませんでした。少なくともFacebookの検索結果ページを下にスクロールすることはできませんでしたが、このソリューションを何度もテストした結果、次のことがわかりました。

while driver.find_element_by_tag_name('div'):
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    Divs=driver.find_element_by_tag_name('div').text
    if 'End of Results' in Divs:
        print 'end'
        break
    else:
        continue

動作しますが、非常に遅いです(少なくとも私にとっては)。stackoverflow.com/a/27760083/7326714をに設定SCROLL_PAUSE_TIMEすると、問題なく機能し、100倍速くスクロールダウンすることがわかりました。2
LucSpan

6

YouTubeで作業する場合、フローティング要素はスクロールの高さとして値「0」を与えるため、「return document.body.scrollHeight」を使用するのではなく、この「return document.documentElement.scrollHeight」を使用して 、インターネットごとにスクロールの一時停止時間を調整してくださいそれ以外の場合は1回だけ実行され、その後中断します。

SCROLL_PAUSE_TIME = 1

# Get scroll height
"""last_height = driver.execute_script("return document.body.scrollHeight")

this dowsnt work due to floating web elements on youtube
"""

last_height = driver.execute_script("return document.documentElement.scrollHeight")
while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0,document.documentElement.scrollHeight);")

    # Wait to load page
    time.sleep(SCROLL_PAUSE_TIME)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.documentElement.scrollHeight")
    if new_height == last_height:
       print("break")
       break
    last_height = new_height

5

動的なWebページをスクロールし、ページの最後に到達すると自動的に停止する方法を探していたところ、このスレッドが見つかりました。

@Cuong Tranによる投稿は、主な変更が1つあり、私が探していた答えでした。私は他の人が修正が役立つと思うかもしれないと思ったので(コードの動作に顕著な影響があります)、それでこの投稿です。

変更は、ループの最後のページの高さをキャプチャするステートメントを移動することです(これにより、各チェックは前のページの高さと比較されます)。

したがって、以下のコード:

動的Webページ(.scrollTo())を下にスクロールし続け、1回の反復でページの高さが同じままの場合にのみ停止します。

(breakステートメントが削除できる別の条件(ページ 'sticks'の場合​​)内にある別の変更があります)。

    SCROLL_PAUSE_TIME = 0.5


    while True:

        # Get scroll height
        ### This is the difference. Moving this *inside* the loop
        ### means that it checks if scrollTo is still scrolling 
        last_height = driver.execute_script("return document.body.scrollHeight")

        # Scroll down to bottom
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        # Wait to load page
        time.sleep(SCROLL_PAUSE_TIME)

        # Calculate new scroll height and compare with last scroll height
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:

            # try again (can be removed)
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

            # Wait to load page
            time.sleep(SCROLL_PAUSE_TIME)

            # Calculate new scroll height and compare with last scroll height
            new_height = driver.execute_script("return document.body.scrollHeight")

            # check if the page height has remained the same
            if new_height == last_height:
                # if so, you are done
                break
            # if not, move on to the next loop
            else:
                last_height = new_height
                continue

5

このコードは一番下までスクロールしますが、毎回待つ必要はありません。継続的にスクロールし、最後に停止します(またはタイムアウトします)。

from selenium import webdriver
import time

driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get('https://example.com')

pre_scroll_height = driver.execute_script('return document.body.scrollHeight;')
run_time, max_run_time = 0, 1
while True:
    iteration_start = time.time()
    # Scroll webpage, the 100 allows for a more 'aggressive' scroll
    driver.execute_script('window.scrollTo(0, 100*document.body.scrollHeight);')

    post_scroll_height = driver.execute_script('return document.body.scrollHeight;')

    scrolled = post_scroll_height != pre_scroll_height
    timed_out = run_time >= max_run_time

    if scrolled:
        run_time = 0
        pre_scroll_height = post_scroll_height
    elif not scrolled and not timed_out:
        run_time += time.time() - iteration_start
    elif not scrolled and timed_out:
        break

# closing the driver is optional 
driver.close()

これは、応答に0.1秒かかる可能性がある場合、応答を毎回0.5〜3秒待つよりもはるかに高速です。


3

読み込みページをスクロールします。例:中、定足数など

last_height = driver.execute_script("return document.body.scrollHeight")
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight-1000);")
        # Wait to load the page.
        driver.implicitly_wait(30) # seconds
        new_height = driver.execute_script("return document.body.scrollHeight")
    
        if new_height == last_height:
            break
        last_height = new_height
        # sleep for 30s
        driver.implicitly_wait(30) # seconds
    driver.quit()

1
driver.quit()はwhileブロックの外にあるべきですか?また、最後の暗黙の待機は必要ありません。誰かが確認します。@ashishmishra
ihightower

1

特定のビュー/フレーム(WebElement)内でスクロールする場合は、「body」を、スクロールする特定の要素に置き換えるだけです。以下の例では「getElementById」を介してその要素を取得します。

self.driver.execute_script('window.scrollTo(0, document.getElementById("page-manager").scrollHeight);')

これは例えばYouTubeの場合です...


1

ScrollTo()機能はもう動作しません。これは私が使用したもので、問題なく動作しました。

driver.execute_script("document.getElementById('mydiv').scrollIntoView();")

私の場合、この方法のみが機能し、他の方法は機能しませんでした。ありがとう。
ePandit

0
driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")

私の場合はうまくいきます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.