在 heroku 上部署后 API 无法正常工作

时间:2021-07-23 07:44:58

标签: python selenium flask

大家好,我最近制作了一个 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)

1 个答案:

答案 0 :(得分:2)

您有一些可以改进的地方。

1/

这是一个糟糕的 xpath:

'/html/body/div[1]/div[1]/div/div[1]/video'

您不想使用完整路径,因为如果 DOM 结构中的任何内容在 htmlvideo 标记之间发生变化,它将失败。 如果您可以共享视频元素的 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")