大家好,我最近制作了一个 python 脚本,它使用 selenium 从 youtube 下载视频,所以我尝试将该脚本转换为 API 并将其部署在 heroku 上,起初它运行良好(但只有一两次),现在我遇到了不同的错误每次我输入从 heroku 获得的 url 时,当我检查日志时,有时它会说“超出内存配额”有时它会说“没有找到这样的元素”,即硒错误,有时它会运行,所以我不确定真正导致什么这是代码:-
import flask
from flask import request
from selenium import webdriver
import os
import time
app = flask.Flask(__name__)
@app.route('/', methods=['GET'])
def home():
url = request.args['url']
mobile_emulation = { "deviceName": "iPhone 6/7/8" }
op = webdriver.ChromeOptions()
op.add_experimental_option("mobileEmulation", mobile_emulation)
op.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
op.add_argument("--headless")
op.add_argument("--no-sandbox")
op.add_argument("--disable-dev-sh-usage")
driver =
webdriver.Chrome(executable_path=os.environ.get("CHROMEDRIVER_PATH"),chrome_options=op)
driver.get(url)
time.sleep(3)
driver.refresh()
element = driver.find_element_by_xpath('/html/body/div[1]/div[1]/div/div[1]/video')
video_source = element.get_attribute('src')
return video_source
if __name__ == "__main__":
app.run(debug=True)
答案 0 :(得分:2)
您有一些可以改进的地方。
1/
这是一个糟糕的 xpath:
'/html/body/div[1]/div[1]/div/div[1]/video'
您不想使用完整路径,因为如果 DOM 结构中的任何内容在 html
和 video
标记之间发生变化,它将失败。
如果您可以共享视频元素的 DOM,我可以帮助您创建一个新的。
2/ 你这样做
driver.get(url)
time.sleep(3)
driver.refresh()
element = driver.find_element_by_xpath('/html/body/div[1]/div[1]/div/div[1]/video')
您等待 3 秒 - 但如果页面需要 4 秒怎么办? (答案是它失败了)。没有对象准备好可用的动态同步。
另外,需要刷新吗? - 这是浏览器刷新以重新加载页面。它基本上会进入页面两次。
看看 selenium 等待策略 here
如果你得到 NoSuchElement,你可以尝试隐式等待:
driver.implicitly_wait(10)
# add this only once - it polls for up to 10 seconds and moves on when ready
如果您得到 ElementNotIteractable(或类似的),您可以尝试显式等待:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/div[1]/div/div[1]/video")))
#(but also update the xpath)
您需要查看 selenium 文档链接以找到合适的预期条件。
3/
默认情况下,--headless
创建一个很小的浏览器窗口。如果您的页面具有动态缩放功能,它将影响 xpath。
将窗口大小设置为您预期的分辨率:
op.add_argument("window-size=1400,600")