无法获取xpath以单击硒中的弹出窗口

时间:2018-08-23 04:54:45

标签: python selenium selenium-webdriver xpath selenium-chromedriver

我正在尝试从SEC提取一些简单的CIK代码。如果您运行下面的代码,您将获得有关“调查”的提示。如果您手动进行操作,则看不到它。它炸毁了我的代码。但是由于它在硒中,所以我无法使用chropath对其进行检查以使xpath单击“ NO”。而且我无法在普通浏览器中重新创建弹出窗口。我该怎么办?

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from random import randint

path ='C:\\Users\\Jason\\Google Drive\\python\\chromedriver.exe' 
ticker='alrm'
main='https://www.sec.gov/search/search.htm'
driver=webdriver.Chrome(path)

tickers=['AAL','AAN','AAOI','AAPL']
# starts the process
def get_CIK(ticker):
    driver.get(main)
    stock_code = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "cik")))
    stock_code.click()
    stock_code.send_keys(ticker)


    driver.find_element_by_xpath("//input[@value='Find Companies']").click() # click on search buttom
    link = driver.find_element_by_xpath("/html[1]/body[1]/div[4]/div[1]/div[3]/span[1]/a[1]").get_attribute("href") # get link
    cik= link[link.index('CIK=')+4:link.index("owner")-1] # extract cik
    print cik

for i in tickers:
    get_CIK(i)

2 个答案:

答案 0 :(得分:2)

您偶尔会看到的是“预见弹出窗口” ,该弹出窗口通常会随机显示。

我可以想到5种通用方法:

  • 设置特定的Cookie ,该Cookie将禁用预示弹出窗口“假装”您已经将其关闭。目前究竟要设置哪个Cookie还是一个悬而未决的问题。也有与此相关的主题:Handle random ForeSee popup using Python and Selenium
  • 在与网站交互期间始终检查“弹出窗口” 的存在。弹出窗口不是硒意义上的经典“警报”,而是只是一个具有以下HTML表示形式的“叠加层”

    <div class="__acs " aria-labelledby="fsrHeading">
        <div class="acsModalBackdrop acsAbandonButton" data-isbackdrop="true">
            <div class="acsFocusFirst acsClassicInvite" tabindex="1"
                 id="acsMainInvite" role="dialog" aria-labelledby="fsrHeading">
                <div class="acsClassicInner" role="document">
                    <div class="acsLogoSpacer"><img
                        src="//gateway.foresee.com/sites/sec-gov/production/trigger/sitelogo.png"
                        class="acsSiteLogo" title="" alt=""> <img
                        src="https://static.foresee.com/logos/foresee/150_67.png"
                        class="acsNoDisplay" title="ForeSee" alt="ForeSee">
                        <div title="ForeSee" alt="ForeSee"
                            class="acsVendorLogoSVG"></div>
                            ... 
    

    例如,您可以然后检查“拒绝”按钮是否存在,然后单击是否存在:

    <a href="#" tabindex="2" class="acsInviteButton acsDeclineButton" title="" role="button"></a>
    
  • 您还可以“阻止”预见要加载的JS脚本,例如,使用浏览器mobproxy来阻止来自“ foresee.com”的所有流量。或者,在类似的轨迹上-您可以使用广告拦截器来启动硒,该广告拦截器可以开箱即用地阻止“预见”

  • ,或者,您可以覆盖“ foresee”全局对象的showInvite()函数

    driver.execute_script("window.FSR.showInvite = function () {};")
    

    请注意,导航到新页面后,您每次都需要调用此脚本。

  • 经过一些逆向工程后,我发现“ foresee” JS对象具有此全局配置,其中包含许多有趣的信息,包括设备黑名单

    device_blacklist: ["HTC_Rezound", "blackberry"]
    

    然后您可以override the browser's user-agent并假装来自Blackberry device

    BLACKBERRY_UA = "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+"
    
    opts = Options()
    opts.add_argument("user-agent={0}".format(BLACKBERRY_UA))
    
    driver = webdriver.Chrome(chrome_options=opts)
    

第二个选项从技术上讲更具挑战性,而且更容易出错,并且会降低速度,因为您将不断检查此弹出窗口是否存在。好吧,至少直到您将其解雇为止。

第四个选项很有希望,但我尚未对其进行全面测试。

最后一个选项,不管听起来多么疯狂,实际上对我有用。

答案 1 :(得分:0)

简而言之

在浏览器的控制台中执行以下脚本时-

driver.execute_script("window.FSR.setFSRVisibility(true);")

它使ForeSee弹出窗口出现在其余HTML元素的后面。而且不再影响UI测试


理论

因此,ForeSee是可以与任何Web应用程序集成的服务之一,并且将通过在网站范围内执行代码来从其API中提取js代码并更改应用程序的HTML。此类公司的另一个示例是walkme

很显然,在现代世界中,如果这些人可以覆盖网页,则他们应该具有使其可选的配置(至少对于较低的环境而言),实际上他们确实可以这样做。我提到的解决方案来自this page。但是,假设他们没有这种选择,则可以向他们寻求支持,并询问如何解决弹出窗口。即使他们没有这样的选择,他们也会很乐意将其视为改进的功能。