【问题标题】:Selenium can find element when run locally but can't find element when run on Heroku serverSelenium 在本地运行时可以找到元素,但在 Heroku 服务器上运行时找不到元素
【发布时间】:2021-09-26 06:31:30
【问题描述】:

当我在本地运行以下代码时,Selenium 能够找到所有元素并且一切正常:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from twilio.rest import Client

account_sid = ACCOUNT_SID
auth_token = AUTH_TOKEN
client = Client(account_sid, auth_token)

def runAmazonXBot():
    driver = webdriver.Chrome(ChromeDriverManager().install())
    driver.get("https://www.amazon.com/Ticonderoga-Wood-Cased-Graphite-Pre-Sharpened-13818/dp/B002VL5IJO/ref=sr_1_5?dchild=1&keywords=pencil&qid=1610946344&sr=8-5")
    driver.find_element_by_xpath("/html//input[@id='buy-now-button']").click()
    driver.find_element_by_xpath("/html//input[@id='ap_email']").send_keys(EMAIL)
    driver.find_element_by_xpath("//span[@id='continue']//input[@id='continue']").click()
    driver.find_element_by_xpath("/html//input[@id='ap_password']").send_keys(PASSWORD)
    driver.find_element_by_xpath("/html//input[@id='signInSubmit']").click()
    driver.find_element_by_xpath("//span[@id='placeYourOrder']//input[@name='placeYourOrder1']").click()

runAmazonXBot()
message = client.messages \
    .create(
        body="Success!",
        from_=PHONE_NUMBER_1,
        to=PHONE_NUMBER_2
    )

但是当我在 Heroku 服务器(涉及 Tweepy)中运行相同的代码时,如下所示:

import tweepy
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import os
from twilio.rest import Client
import traceback2 as traceback

chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--no-sandbox")
driver = webdriver.Chrome(executable_path=os.environ.get("CHROMEDRIVER_PATH"), chrome_options=chrome_options)

consumer_key = CONSUMER_KEY
consumer_secret = CONSUMER_SECRET
access_token = ACCESS_TOKEN
access_token_secret = ACCESS_TOKEN_SECRET

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

api = tweepy.API(auth)

def copAmazon():
    chrome_options = webdriver.ChromeOptions()
    chrome_options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--no-sandbox")
    driver = webdriver.Chrome(executable_path=os.environ.get("CHROMEDRIVER_PATH"), chrome_options=chrome_options)
    driver.get("https://www.amazon.com/Ticonderoga-Wood-Cased-Graphite-Pre-Sharpened-13818/dp/B002VL5IJO/ref=sr_1_5?dchild=1&keywords=pencil&qid=1610946344&sr=8-5")
    driver.find_element_by_xpath("/html//input[@id='buy-now-button']").click()
    driver.find_element_by_xpath("/html//input[@id='ap_email']").send_keys(EMAIL)
    driver.find_element_by_xpath("//span[@id='continue']//input[@id='continue']").click()
    driver.find_element_by_xpath("/html//input[@id='ap_password']").send_keys(PASSWORD)
    driver.find_element_by_xpath("/html//input[@id='signInSubmit']").click()
    driver.find_element_by_xpath("//span[@id='placeYourOrder']//input[@name='placeYourOrder1']").click()

account_sid = ACCOUNT_SID
auth_token = AUTH_TOKEN
client = Client(account_sid, auth_token)
class MyStreamListener(tweepy.StreamListener):
    def on_status(self, status):
        if status.user.id_str == TWITTER_ID:
            try:
                copAmazon()
                message = client.messages \
                    .create(
                        body='Success!',
                        from_=PHONE_NUMBER_1,
                        to=PHONE_NUMBER_2
                    )
            except:
                message = client.messages \
                    .create(
                        body='Fail! ' + traceback.format_exc(),
                        from_=PHONE_NUMBER_1,
                        to=PHONE_NUMBER_2
                    )

myStreamListener = MyStreamListener()
myStream = tweepy.Stream(auth = api.auth, listener=myStreamListener)
myStream.filter(follow=[TWITTER_ID])

我收到以下错误:“selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//span[@id ='placeYourOrder']//输入[@name='placeYourOrder1']"} (会话信息:headless chrome=91.0.4472.164)"

基本上,当我在本地运行代码时,Selenium 可以很好地找到元素,但是当代码在 Heroku 服务器上运行时,Selenium 无法找到元素。为什么是这样?我很确定我已经正确设置了所有的构建包。此外,在上面的两个代码块中,ACCOUNT_SID、AUTH_TOKEN、PHONE_NUMBER_1、PHONE_NUMBER_2、CONSUMER_KEY、CONSUMER_SECRET、ACCESS_TOKEN、ACCESS_TOKEN_SECRET、EMAIL、PASSWORD 和 TWITTER_ID 都是正确的值(宏仅用于隐私目的)。有任何想法吗?谢谢!

【问题讨论】:

  • 你能在 Heroku 上以常规模式运行代码,而不是无头模式吗?
  • 我该怎么做?
  • 只需删除 chrome_options.add_argument("--headless")
  • 不幸的是,这并没有解决我的问题
  • 通过代码下订单似乎是一个非常糟糕的主意。请记住,总是有错误!在这种情况下,一个错误可能会毁掉您的银行帐户。

标签: python selenium heroku


【解决方案1】:

所以我弄清楚了为什么会这样。我刚刚注意到,每次在 Heroku 服务器上运行脚本时,我都会从亚马逊收到一条文本,说有“来自美国弗吉尼亚州的登录尝试”(这是 Heroku 服务器所在的位置),这意味着我必须先批准它,然后 Selenium ChromeDriver 才能继续。这就是 ChromeDriver 在登录后无法立即找到“下订单”按钮的原因。我将尝试找到一种方法让 Amazon 停止此验证过程,以便 ChromeDriver 在登录后不会停止,然后可以找到“下订单”按钮。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    相关资源
    最近更新 更多