ale*_*its 16 javascript python python-3.x playwright
我正在尝试使用 Python 和 Playwright 自动抓取具有“无限滚动”功能的网站。
问题是,到目前为止,Playwright 还不包含滚动功能,更不用说无限自动滚动功能了。
根据我在网上发现的内容和我的个人测试,我可以使用该page.evaluate()函数和一些 Javascript 代码自动执行无限或有限滚动。
例如,这有效:
for i in range(20):
page.evaluate('var div = document.getElementsByClassName("comment-container")[0];div.scrollTop = div.scrollHeight')
page.wait_for_timeout(500)
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于,它要么通过指定滚动数量,要么通过告诉它永远循环下去来工作while True。
我需要找到一种方法来告诉它继续滚动,直到加载最终内容。
这是我目前正在尝试的 Javascript page.evaluate():
var intervalID = setInterval(function() {
var scrollingElement = (document.scrollingElement || document.body);
scrollingElement.scrollTop = scrollingElement.scrollHeight;
console.log('fail')
}, 1000);
var anotherID = setInterval(function() {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
clearInterval(intervalID);
}}, 1000)
Run Code Online (Sandbox Code Playgroud)
这在我的 Firefox 浏览器或 Playwright 的 Firefox 浏览器中都不起作用。它立即返回并且不会间隔执行代码。
如果有人能告诉我如何使用 Playwright 创建一个自动滚动功能,该功能将在到达动态加载网页的底部时检测并停止,我将不胜感激。
ale*_*its 17
所以我找到了一个可行的解决方案。
我所做的是将 Javascript 与 python Playwright 代码结合起来。
我用 200ms 的计时器启动 setInterval 在页面上向下滚动page.evaluate(),然后用 python 循环跟踪它,每秒检查页面的总高度(包括滚动)是否已更改。如果发生变化,则继续滚动,如果没有变化,则滚动结束。
它看起来是这样的:
page.evaluate(
"""
var intervalID = setInterval(function () {
var scrollingElement = (document.scrollingElement || document.body);
scrollingElement.scrollTop = scrollingElement.scrollHeight;
}, 200);
"""
)
prev_height = None
while True:
curr_height = page.evaluate('(window.innerHeight + window.scrollY)')
if not prev_height:
prev_height = curr_height
time.sleep(1)
elif prev_height == curr_height:
page.evaluate('clearInterval(intervalID)')
break
else:
prev_height = curr_height
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)
请使用新的 mouse.wheel(x, y) 功能查看下面的答案,了解使用 playwright 进行滚动的最新方式。将我的答案与他的答案结合起来,以减少使用 JS 的需要。
小智 15
新的剧作家版本具有滚动功能。它被称为mouse.wheel(x, y). 在下面的代码中,我们将尝试滚动浏览具有“无限滚动”的 youtube.com:
from playwright.sync_api import Playwright, sync_playwright
import time
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
# Open new page
page = context.new_page()
page.goto('https://www.youtube.com/')
# page.mouse.wheel(horizontally, vertically(positive is
# scrolling down, negative is scrolling up)
for i in range(5): #make the range as long as needed
page.mouse.wheel(0, 15000)
time.sleep(2)
time.sleep(15)
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
Run Code Online (Sandbox Code Playgroud)
小智 9
其他解决方案对我来说有点冗长和“矫枉过正”,而这对我有用。
这是一个两眼线,让我有些偏头痛才过来:)
注意:您必须输入自己的选择器。这只是一个例子......
while page.locator("span",has_text="End of results").is_visible() is False:
page.mouse.wheel(0,100)
#page.keyboard.down(PageDown) also works
Run Code Online (Sandbox Code Playgroud)
从字面上看,只是继续滚动,直到出现某种独特的选择器。在这种情况下,当您滚动到底部时,会弹出带有字符串“结果结束”(针对我的用例的上下文)的跨度标记。
我相信你可以翻译这个逻辑以供你自己使用。
| 归档时间: |
|
| 查看次数: |
36443 次 |
| 最近记录: |