硒+;Python如何侦听元素的更改
其想法是创建一个bot来读取聊天中的消息,并且所有消息都位于硒+;Python如何侦听元素的更改,python,selenium,selenium-webdriver,Python,Selenium,Selenium Webdriver,其想法是创建一个bot来读取聊天中的消息,并且所有消息都位于ul>li(不需要编写消息),例如 你好 你好 我从Selenium中找到了expected_conditions,以处理元素是否存在/找到,但它始终是真的,因为有消息,但如果消息已经在聊天中,我不想继续编写代码,这不是主要思想。在那之后,我发现了EventFiringWebDriver、AbstractEventListener什么都没有 从selenium导入webdriver作为wb 从selenium.webdri
ul>li
(不需要编写消息),例如
我从Selenium中找到了expected_conditions
,以处理元素是否存在/找到,但它始终是真的,因为有消息,但如果消息已经在聊天中,我不想继续编写代码,这不是主要思想。在那之后,我发现了EventFiringWebDriver、AbstractEventListener
什么都没有
从selenium导入webdriver作为wb
从selenium.webdriver.support.ui导入WebDriverWait
从selenium.webdriver.support.events导入EventFiringWebDriver,AbstractEventListener
从selenium.webdriver.common.keys导入密钥
类MyListener(AbstractEventListener):
在导航到之前定义(自身、url、驱动程序):
打印(“导航到%s”%url之前)
def after_导航到(self、url、driver):
打印(“导航到%s”%url后)
driver=wb.Chrome('C:\python\selenium\chromedriver.exe')
wait=WebDriverWait(驱动程序,300)
#ef_driver=EventFiringWebDriver(驱动程序,MyListener())
驱动程序。隐式等待(15)
司机,上车https://socket.io/demos/chat/')
driver.switch_to.frame(driver.find_element_by_class_name('iframe-class'))
InputName=driver。通过xpath('/html/body/ul/li[2]/div/input')查找元素
InputName.send_键('MyNameIsJeff')
输入名称。发送密钥(密钥。输入)
您可以在循环中执行某种侦听器,检查消息元素的文本以确定它是否是新消息,您只需确定一个设置的时间范围,您希望在“检查”之间等待10秒、30秒、1分钟等
我认为你不需要一个事件监听器。您只需抓取最新消息,然后继续检查它,看看它是否与以前的值不同
from time import sleep
# get list of currently displayed messages
messages = driver.find_elements_by_xpath("//li[@class='message']")
# get text from most recent message
# depending on element order on the page, might need to do messages.last
last_message_text = messages[0].text
# do something here to trigger a new message coming in?
# wait for last_message_text to be something different
while (true):
# get list of currently displayed messages
messages = driver.find_elements_by_xpath("//li[@class='message']")
# new message has arrived if we hit this statement
if (messages[0].text != last_message_text) break;
# wait 15 seconds
sleep(15)
此示例将获取当前显示的消息列表。然后,它获取最后接收到的消息。代码进入循环并重新获取消息列表,检查最后收到的消息,并将其文本与我们先前保存的最后一条消息值进行比较
如果最后收到的消息与保存的值不同,循环将中断,这意味着新消息已到达
这里有一些不清楚的地方——最近的消息可能是消息
列表中的第一个元素,也可能是最后一个元素。另一个问题——你是否在做一些事情来触发新消息的出现?例如InputName.send_key('MyNameIsJeff')
?如果是这种情况,代码的顺序可能需要更改一点
最后——在您的评论中,您提到有时
ul
是空的。我不确定这意味着什么,但是如果出现一些消息,并且页面上没有HTML,那么这个解决方案就不会真正起作用。我认为您可以编写一个循环,在循环中,获取所需“ul”中的“li”数。如果“li”的数量增加,则会有一条新消息
# get list of li inside of ul
ulList = driver.find_elements_by_xpath("//ul[@class='message-list']")
lenOfLis = len(ulList)
# wait for new message...
while (true):
ulList = driver.find_elements_by_xpath("//ul[@class='message-list']")
if (len(ulList) > lenOfLis): # you have new message
for (i in range(len(ulList)-lenOfLis)):
yourLastMessage = ulList[-1-(i-1)]
# you can do whatever you want with your last messages
LenOfLis = len(ulList) # update length of ul
# wait 15 seconds
sleep(5)
所有消息都在一个li中吗?是的,任何新消息都将添加一个
li
到ul
编辑:对不起,所有消息都在ul
中,每条消息都是一个新的li
,因此我想您可以计算li的数量。检查数字是否增加,这意味着您有一条新消息,您可以阅读“li”最后一个元素的内容。我尝试过。但如果有人发送一条新消息,它会在进入聊天室时计算消息数,但不会计算消息数,例如Bot enter to chat,此聊天室具有:
为空,因为刚刚输入,因此循环为0,如果一些人发送新消息,ul
将不会为空,但循环已完成,因此。。。如果出现新消息,如何返回?有一个监听器,对吗?我认为最简单的方法是写一个循环。在循环内部等待几秒钟,找到元素并获得“li”的长度,然后将其传递给变量。我认为在这种情况下,不会通知您消息是相同的。用户不关心消息是否相同。他们只想知道是否有新消息到达。此外,我们知道,如果命中time.sleep
语句,消息是相同的。这是一个好主意,但不是一个好的处理方法。如果用户在这5秒钟内发送2条消息会怎么样?机器人不会阅读第一条信息,只会阅读最后一条。我以为Selenium有一些DOM更改事件处理程序之类的东西。你说得对。解决方案是,如果长度发生了变化,您可以找到差异并从列表中写入这些元素。那么,如何知道长度是否发生了变化?使用当前循环,我们可以消除睡眠,但在这之后,我不知道,1-3分钟对计算机不好。需要一些“事件”来说“嘿!长度已更改,请转到“我编辑了代码”。我想它会起作用的。现在我在手机上,无法查看:)