简单的 Selenium 爬虫应用及定时桌面提示图示

文件建立日期: 2020/03/11
最后修订日期:
2020/03/16 (代码更新 - 没讯息也显示, 有讯息更新时间变短)
2020/03/27 (代码更新 - 忘了改了什么)
2020/04/14 (图片使用PySimpleGUI内部图片, 代码变得更简短)
2020/04/15 (因视窗的标题可能不同, 加注自行提示修改)
2020/04/21 (新增 IE 版本)
2020/06/02 (新增 Chrome 版本与 chromedriver.exe 不符提示)
2020/06/28 (SystemTray.notify removed, replaced by show_message)

相关软件信息

Win10 Python 3.8.3
PySimpleGUI 4.20.0.11 Selenium 3.141.0
pywin32 227 Google Chrome 83.0.4103.106
ChromeDriver 83.0.4103.39

说明: 本文请随意引用或更改, 只须标示出处及作者, 作者不保证内容絶对正确无误, 如造成任何后果, 请自行负责.

标题: 简单的 Selenium 爬虫应用及定时桌面提示图示

在LearnKu上常有一些讯息通知, 没有检视就看不到, 所以就顺手写了一个桌面通知程序.

要求

  1. 使用selenium
  2. 为了保护帐户/密码, 在程序启动后再输入登入
  3. 运行后只留一个图示在桌面, 右键点选开始及结束
  4. 登入后, 点选开始, 隐藏chrome网页以及chromedriver窗口
  5. 每5分钟通知出现一次

简单的 Selenium 爬虫应用及定时桌面提示图示

代码及说明

  1. 库的载入 (如果你使用 PySimpleGUIWx, 而不是 PySimpleGUI, 提示图示會并入工作列)
import PySimpleGUI as sg
from PySimpleGUI import DEFAULT_BASE64_ICON as logo
import win32gui
from selenium import webdriver
  1. 讯息通知
    读取讯息数通知, 五分钟通知一次, 有讯息改为30秒通知一次
<span class="ui basic circular label notification" id="notification-count">
                0
            </span>
def notify():
    global timeout
    elements = driver.find_elements_by_id("notification-count")
    if elements != []:
        try:
            count = int(elements[0].text)
        except:
            count = 0
        if count > 0:
            timeout = 30000
            tray.show_message('Notify', f'{count} new messages')
        else:
            timeout = 300000
            tray.show_message('Notify', 'No new messages')
  1. 隐藏窗口, 如果标题与要求的一样, 设置窗口隐藏.
    注意1: 如果登入错误, 因为标题改变, 可能会找不到视窗隐藏
    注意2: 标题可能因為环境不同而有異, 请自行检查两个视窗的标题, 進行修改.
def enumWindowFunc(hwnd, windowList):
    """ win32gui.EnumWindows() callback """
    text = win32gui.GetWindowText(hwnd)
    className = win32gui.GetClassName(hwnd)
    title = 'chromedriver.exe'
    if title.lower() in text.lower() or title in className.lower():
        win32gui.ShowWindow(hwnd, False)
        # print('chromedriver hide')
    title = 'Python 技术论坛 | 高品质的 Python 开发者社区'.lower()
    if title.lower() in text.lower() or title in className.lower():
        win32gui.ShowWindow(hwnd, False)
        # print('learnku hide')
  1. 启动chrome驱动, 开启网页并读取
try:
    driver = webdriver.Chrome('D:/Python/Project/chromedriver')
except:
    sg.popup('Crome driver load failed, maybe wrong version !')
    quit()
driver.get('https://learnku.com/python')
  1. 建立图示, 并设置右键菜单为StartQuit
menu_def = ['My_Menu', ['Start', 'Quit']]
tray = sg.SystemTray(menu=menu_def, data_base64=logo)
  1. 右键事件处理以及讯息通知更新
timeout = 300000
flag = False
while True:

    event = tray.read(timeout=timeout)

    if event in [None, 'Quit']:
        break

    if flag:
        try:
            driver.refresh()
            notify()
        except:
            pass
    else:
        if event == 'Start':
            win32gui.EnumWindows(enumWindowFunc, [])
            # driver.minimize_window()
            notify()
            flag = True

driver.close()
driver.quit()
tray.close()
  1. IE 版
import PySimpleGUI as sg
from PySimpleGUI import DEFAULT_BASE64_ICON as logo
import win32gui
from selenium import webdriver

def notify():
    global timeout
    elements = driver.find_elements_by_id("notification-count")
    if elements != []:
        try:
            count = int(elements[0].text)
        except:
            count = 0
        if count > 0:
            timeout = 30000
            tray.show_message('Notify', f'{count} new messages')
        else:
            timeout = 300000
            tray.show_message('Notify', 'No new messages')

def enumWindowFunc(hwnd, windowList):
    """ win32gui.EnumWindows() callback """
    text = win32gui.GetWindowText(hwnd)
    className = win32gui.GetClassName(hwnd)
    if 'IEDriverServer.exe' in text or 'Python 开发者社区' in text:
        win32gui.ShowWindow(hwnd, False)

driver = webdriver.Ie('D:/Python/Project/IEDriverServer.exe')
driver.get('https://learnku.com/python')

menu_def = ['My_Menu', ['Start', 'Quit']]
tray = sg.SystemTray(menu=menu_def, data_base64=logo)
timeout = 300000
flag = False
while True:

    event = tray.read(timeout=timeout)

    if event in [None, 'Quit']:
        break

    if flag:
        try:
            driver.refresh()
            notify()
        except:
            pass
    else:
        if event == 'Start':
            win32gui.EnumWindows(enumWindowFunc, [])
            notify()
            flag = True

driver.close()
driver.quit()
tray.close()
本作品采用《CC 协议》,转载必须注明作者和本文链接
Jason Yang
本帖由系统于 4年前 自动加精
讨论数量: 11

请问不同方法直接如何传递driver?

4年前 评论
Jason990420

我也不是什么都知道的, 所有的库我都是直接查资料, 一边看一边用...
不过看不懂
"不同方法直接如何传递 driver?"
这是问什么? 完了, 我竟然看不懂这句中文...... 最好是有例子, 想怎么用 ?

4年前 评论

您那有selenium自动化项目的例子吗?我想学习一下,我所说的传递driver就比如,登录方法之后,另一个方法可能会到另一个页面进行其他操作的情况,如何来进行传递

4年前 评论
GA17 3年前

我是想实现用两个业务逻辑的方法,实现两个操作,比如登录和收发文为两个单独的方法,这之间的driver该如何传递,用类的封装实现,

4年前 评论
Jason990420

例子没有现成的, 至于参数传递, 就像Python一样啊

  1. local variable
  2. Global variable
  3. Class attributes
  4. paramters/arguments
  5. file/database/memory I/O
  6. 其他 至于哪一个好, 看情况而定, 一般来说, 我觉得函数的参数传递最好, 因为可以单独测试函数, 不会受环境状态影响, 不好的是参数多了句子就长了. 其他的都是隐式处理, 你可能会不知道该变量, 什么时候被修改了, 不过Global和Class在出错时, 都还能检视内容, 用来除错.
4年前 评论
Jason990420
pip install pywin32
4年前 评论
Coolest 4年前
Coolest 4年前

大佬的chrome驱动版本是多少?chrome的版本又是多少?可以说一下吗

4年前 评论
Jason990420

Google Chrome 目前是最新版本
版本 80.0.3987.149 (正式版本) (64 位元)
If you are using Chrome version 80, please download ChromeDriver 80.0.3987.106
https://chromedriver.storage.googleapis.co...

4年前 评论
Coolest 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!