使用 Selenium 和 PhantomJS 单击按钮并填写表单

Posted

技术标签:

【中文标题】使用 Selenium 和 PhantomJS 单击按钮并填写表单【英文标题】:Clicking buttons and filling forms with Selenium and PhantomJS 【发布时间】:2016-07-26 16:09:21 【问题描述】:

我有一个想要自动化的简单任务。我想打开一个 URL,单击一个按钮,将我带到下一页,填写搜索词,单击“搜索”按钮并打印出结果页面的 url 和源代码。我已经写了以下内容。

from selenium import webdriver
import time

driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)

#open URL
driver.get("https://www.searchiqs.com/nybro/")
time.sleep(5)

#click Log In as Guest button
driver.find_element_by_id('btnGuestLogin').click()
time.sleep(5)

#insert search term into Party 1 form field and then search
driver.find_element_by_id('ContentPlaceholder1_txtName').send_keys("Moses")
driver.find_element_by_id('ContentPlaceholder1_cmdSearch').click()
time.sleep(10)

#print and source code
print driver.current_url
print driver.page_source
driver.quit()

我不确定我哪里出错了,但我已经遵循了一些关于如何单击按钮和填写表单的教程。我得到了这个错误。

Traceback (most recent call last):                                                                                                                                              
  File "phant.py", line 12, in <module>                                                                                                                                         
    driver.find_element_by_id('btnGuestLogin').click()                                                                                                                          
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 269, in find_element_by_id                                                         
    return self.find_element(by=By.ID, value=id_)                                                                                                                               
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 752, in find_element                                                               
    'value': value)['value']                                                                                                                                                   
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute                                                                    
    self.error_handler.check_response(response)                                                                                                                                 
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response                                                          
    raise exception_class(message, screen, stacktrace)                                                                                                                          
selenium.common.exceptions.NoSuchElementException: Message: "errorMessage":"Unable to find element with id 'btnGuestLogin'","request":"headers":"Accept":"application/json","
Accept-Encoding":"identity","Connection":"close","Content-Length":"94","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:35670","User-Agent":"Python-urllib/2.7"
,"httpVersion":"1.1","method":"POST","post":"\"using\": \"id\", \"sessionId\": \"d38e5fa0-5349-11e6-b0c2-758ad3d2c65e\", \"value\": \"btnGuestLogin\"","url":"/element","urlP
arsed":"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":""
,"protocol":"","source":"/element","queryKey":,"chunks":["element"],"urlOriginal":"/session/d38e5fa0-5349-11e6-b0c2-758ad3d2c65e/element"                                  
Screenshot: available via screen

该错误似乎表明具有该 id 的元素尚不存在。

--- 编辑:更改代码以使用 WebDriverWait ---

我已经改变了一些东西来实现 WebDriverWait

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)

#open URL
driver.get("https://www.searchiqs.com/nybro/")

#click Log In as Guest button
element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "btnGuestLogin"))
        )
element.click()

#wait for new page to load, fill in form and hit search
element2 = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "ContentPlaceholder1_cmdSearch"))
        )
#insert search term into Party 1 form field and then search
driver.find_element_by_id('ContentPlaceholder1_txtName').send_keys("Moses")
element2.click()
driver.implicitly_wait(10)

#print and source code
print driver.current_url
print driver.page_source
driver.quit()

它仍然会引发此错误

Traceback (most recent call last):                                                                                                                                              
  File "phant.py", line 14, in <module>                                                                                                                                         
    EC.presence_of_element_located((By.ID, "btnGuestLogin"))                                                                                                                    
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/support/wait.py", line 80, in until                                                                           
    raise TimeoutException(message, screen, stacktrace)                                                                                                                         
selenium.common.exceptions.TimeoutException: Message:                                                                                                                           
Screenshot: available via screen

【问题讨论】:

看看周围有没有框架...或者需要实现WebDriverWait等到元素可见和可点击而不是time.sleep...:) @SaurabhGaur,我已经进行了编辑,您可以在帖子底部使用新的替代脚本看到它们。我仍然收到错误 那么框架呢??...确保btnGuestLogin不在任何框架或iframe中 @SaurabhGaur ,它不在框架中。我检查了页面源,没有框架。 【参考方案1】:

WebDriverWait 方法实际上对我有效:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)

driver.get("https://www.searchiqs.com/nybro/")

element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "btnGuestLogin"))
        )
element.click()

没有错误。 PhantomJS 版本 2.1.1、Selenium 2.53.6、Python 2.7。


该问题可能与 SSL 和 PhantomJS 有关,可以通过 http 解决:

driver.get("http://www.searchiqs.com/nybro/")

或者,试试ignoring SSL errors:

driver = webdriver.PhantomJS(service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])

【讨论】:

@TendekaiMuchenje 好的,打印页面源代码,你得到了什么? print(driver.page_source). 如果我在做driver.get() 之后把它写出来,它会打印出&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;,之后的任何地方都会导致错误 @TendekaiMuchenje 好的,看到你有空页面源。尝试添加'--ssl-protocol=any' 参数,更新答案。 我仍然遇到同样的错误。我不确定为什么。我将“www.google.com”切换为我的网站,但它仍然给了我空白页面源。 成功了!感谢您的帮助!

以上是关于使用 Selenium 和 PhantomJS 单击按钮并填写表单的主要内容,如果未能解决你的问题,请参考以下文章

如何为搜索引擎优化 PhantomJS 以索引单页应用程序?

使用selenium和phantomJS浏览器获取网页内容的小演示

scrapy使用PhantomJS和selenium爬取数据

使用 Selenium 和 PhantomJS 将 javascript polyfill 注入页面

使用 Python/PhantomJS/Selenium 滚动无限页面

C#使用Selenium+PhantomJS抓取数据