使用 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()
之后把它写出来,它会打印出<html><head></head><body></body></html>
,之后的任何地方都会导致错误
@TendekaiMuchenje 好的,看到你有空页面源。尝试添加'--ssl-protocol=any'
参数,更新答案。
我仍然遇到同样的错误。我不确定为什么。我将“www.google.com”切换为我的网站,但它仍然给了我空白页面源。
成功了!感谢您的帮助!以上是关于使用 Selenium 和 PhantomJS 单击按钮并填写表单的主要内容,如果未能解决你的问题,请参考以下文章
如何为搜索引擎优化 PhantomJS 以索引单页应用程序?
使用selenium和phantomJS浏览器获取网页内容的小演示
scrapy使用PhantomJS和selenium爬取数据
使用 Selenium 和 PhantomJS 将 javascript polyfill 注入页面