我试图使用" whatsapp -web“、"selenium”和"python 3“来了解whatsapp用户何时上线或离线。
为了解释更多,我希望脚本工作如下:
脚本将侦听要显示的span (带有title=online),当span显示时(这意味着用户在线),我希望此时打印时间,然后脚本将继续侦听以使span消失,当脚本消失时,脚本打印消失的时间,等等。
这是我的密码:
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 datetime
driver = webdriver.Chrome('C:/webdrivers/chromedriver.exe')
driver.get('https://web.whatsapp.com/')
# do nothing until QR code scanned and whatsapp-web is accessed
input('Enter anything after scanning QR code')
# Input the name of the user to track
name = input('Enter the name of the user : ')
# find the whatsapp user to be tracked then a click to enter the conversation
user = driver.find_element_by_xpath("//span[@title = '{}']".format(name))
user.click()
while True:
# in the conversation page, a span with title online is diplayed when user is online.
#the web driver will wait 8hrs=28800s, if user not online all this time script will be killed by webdriverWait
element = WebDriverWait(driver, 28800).until(
EC.visibility_of_element_located(
(By.XPATH, "//span[@title = 'online']")))
#Moment the user came online
now = datetime.datetime.now()
print("online at : ")
print(now.strftime("%H:%M:%S"))
element = WebDriverWait(driver, 28800).until(
EC.invisibility_of_element_located(
(By.XPATH, "//span[@title = 'online']")))
#Moment the user went offline
now = datetime.datetime.now()
print("offline at : ")
print(now.strftime("%H:%M:%S"))
print("************")
我的脚本可以工作,但是,我希望它运行几个小时,比如8小时甚至更长时间,但我读到使用坏实践时使用WebDriverWait的时间很长(在我的例子中是28800秒)。
,那么还有其他更好的方法来实现这一点吗?
如何将输出写入txt或word文件?
有让我的代码更好的建议吗?
如何防止CPU猛击?或任何可能发生的问题
发布于 2019-01-18 06:58:43
WebDriverWait
不过是(相当)花哨的同时/捕捉/睡眠循环;在您的特殊情况下,您可能希望自己复制它,原因很简单--它每500毫秒进行一次投票,对于这项任务来说,这可能太详细了。它也能保护你不受更细粒度的控制。
下面是如何自己执行逻辑的方法--有一个布尔变量是用户在线与否;根据它的值,check是可见元素(.is_displayed()
),睡眠X时间和重复。异常NoSuchElementException
,StaleElementReferenceException
将计算为脱机用户/布尔值false。
最后,您的代码将非常接近WebDriverWait
中的逻辑--尽管如此,如果需要,您的代码也会更加灵活。
或者,只需在当前代码中的WebDriverWait
内部传递一个更大的轮询-它是调用的poll_frequency
参数:)
WebDriverWait(driver, 28800, 5) # the value is in seconds
我不知道你在哪里读到了什么--用很长的时间使用WebDriverWait是不好的做法;正如您在它的代码中所看到的,它只是给该方法运行的时间而已。
我猜想这条建议是以“用大量秒来使用WebDriverWait是一种不好的做法,因为如果条件在X秒内没有得到满足,它将永远不会被满足,而您的代码只会旋转和旋转。”这实际上是您想要的行为:)
我也不会担心对cpu征税--这些检查非常轻巧,没有什么害处。对于这个大的运行时,我担心的是浏览器本身的内存泄漏;)
至于优化代码,我要做的是减少语句的重复,这样做的缺点是降低了代码的可读性。我对循环的看法:
user_online = False
while True:
# we'll be checking for the reverse of the last status of the user
check_method = EC.visibility_of_element_located if not user_online else EC.invisibility_of_element_located
# in the conversation page, a span with title online is diplayed when user is online.
# the web driver will wait 8hrs=28800s for the user status to change all
# the script will be killed by webdriverWait if that doesn't happen
element = WebDriverWait(driver, 28800, 5).until(
check_method((By.XPATH, "//span[@title = 'online']")))
# The moment the user changed status
now = datetime.datetime.now().strftime("%H:%M:%S")
print("{} at : {}".format('online' if not user_online else 'offline', now)) # if you're using python v3.6 or more, the fstrings are much more convenient for this
print("************")
user_online = not user_online # switch, to wait for the other status in the next cycle
最后,就代码而言,不能让脚本“没完没了地”运行。为什么?因为如果用户在8小时内不改变状态,WebDriverWait
就会停止。若要挽救该问题,请将循环主体封装在try/except中:
from selenium.common.exceptions import TimeoutException # put this in the beginning of the file
while True:
try:
# the code from above
except TimeoutException:
# the status did not change, repeat the cycle
pass
写入文件
您可能需要阅读 a 位 how 要做到这一点 -这是一个非常简单的操作。
下面是一个示例-打开一个用于追加的文件(因此保留了以前的日志),包装while
循环:
with open("usermonitor.log", "a") as myfile:
while True:
# the other code is not repaeted for brevity
# ...
output = "{} at : {}".format('online' if not user_online else 'offline', now)
print(output)
myfile.write(output + "\n") # this will write (append as the last line) the same text in the file
# write() does not append newlines by itself - you have to do it yourself
发布于 2021-07-22 21:19:20
我要建议的是,在您的程序中,每次执行此程序时都需要扫描whatsapp,只需替换这一行。
driver = webdriver.Chrome('C:/webdrivers/chromedriver.exe')
有了这个
driver = webdriver.Chrome('C:/webdrivers/chromedriver.exe', options="user-data-dir=C:\\Users\\<username>\\AppData\\Local\\Google\\Chrome\\User Data\\whtsap")
这样你就需要扫描QR,但只需要扫描一次。
https://stackoverflow.com/questions/54246168
复制相似问题