起因
出于某种不可明说的目的和某些不可明说的需求,需要一个自动签到脚本,权衡之下使用了selenium库,之所以不用更快更稳定的request是因为这个网站登录的时候会对密码做加密,抓包抓到的密码每次都不一样,不知道怎么搞,所以选了更简单的方案。
运行环境
使用的是selenium库,这个库可以模拟人在浏览器上的操作,简单易懂。
首先安装
pip install selenium
我使用的是chrome浏览器,需要下载对应版本的浏览器驱动才可以使用selenium自动控制,在windows上很简单,先查询浏览器版本,打开chrome,地址栏输入Chrome://version,就能看到版本。 然后去驱动下载地址http://chromedriver.storage.googleapis.com/index.html,找到对应的驱动,可能没有完全对应浏览器版本号的的驱动,最后两位可以不同。 然后下载下来,具体安装步骤参考这篇博客https://blog.csdn.net/weixin_44318830/article/details/103339273 安装好后,可以尝试运行这段代码来判断运行环境是否正常。
from selenium import webdriver
browser = webdriver.Chrome()#声明浏览器
url = 'https:www.baidu.com'
browser.get(url)
print(browser.page_source)#打印网页源代码
browser.close()#关闭浏览器
如果能成功打印,说明环境一切正常,进入下一步,编写我们自己的脚本。
自动签到部分
简单来说,selenium就是模拟人在浏览器上的操作,我们只要找到需要操作的位置,例如需要填写账号密码的文本框,或者需要点击的按钮,然后使用代码模拟我们的填写或者点击操作。
首先,和上面测试环境的代码类似,我们要打开浏览器,访问需要签到的网址。
from selenium import webdriver
browser = webdriver.Chrome()
url = '这里填要签到的网址'
browser.ger(url)
然后需要插一个简单的小知识,如何在网页上找到我们需要操作的按钮,或者文本框,以chrome浏览器为例,我们需要在这个页面上找到这个按钮。
在chrome浏览器中,点击F12,打开开发者界面。
开发者界面如图所示,点击选择器。 然后在网页上点击要找的按钮,元素这里就会找到网页中这个按钮对应的html代码。 鼠标右键点击对应的代码,选择复制,复制完整xpath。 XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言,可以简单理解为代表一个元素在网页中的位置,可以用xpath定位一个元素。
接下来回到刚才的内容,在打开网页之后,首先我们需要登录。 这里我们一共需要做三件事,首先输入用户名,然后输入密码,然后点击登录,所以先按照上面的方法找到两个需要输入的文本框的位置,输入用户名和密码,然后找到登录按钮的位置,点击。
这里使用find_element_by_xpath方法,通过xpath定位到需要操作的元素。
from selenium import webdriver
browser = webdriver.Chrome()
url = '这里填要签到的网址'
browser.ger(url)
username_xpath = 'xxxx'#用户名的xpath
passwd_xpath = 'xxxx'#密码的xpath
login_button_xpath = 'xxxx'#登录按钮的xpath
username = 'username'#用户名
passwd = 'passwd'#密码
browser.find_element_by_xpath(username_xpath).send_keys(username)#定位用户名输入框,并输入用户名
browser.find_element_by_xpath(passwd_xpath).send_keys(passwd)#定位密码输入框,并输入密码
browser.find_element_by_xpath(login_xpath).click()#找到登录按钮并点击
以上代码执行完后,如果没有验证码,我们就登录到了系统,如果有验证码算你倒霉。 剩下的操作与上面类似,签到无非就是输入文字和点击按钮,只要找到相应的元素,然后依次点击就可以,之后的步骤不再赘述。
剩下需要注意的问题有两个,我们一个一个说。
第一个问题是,有时候在点击当前页面的按钮之后,会打开一个新的标签页,接下来的操作需要在新的页面上做,此时该怎么办?
首先我们要知道,上文中用于操作的browser是和页面对应的,在点击按钮打开新的标签页后,browser并不会自动跳转到新的标签页,这时候就需要我们手动跳转。假设登录之后,我们点击了一个按钮button1,打开了一个新的标签页,之后要在新标签页上点击button2,我们对以上的代码加以改造。首先我们需要获取所有标签页的handle集合,可以把handle简单理解为标签页的代号,只要找到要切换的标签页代号,就能切换到新的标签页。在获取所有标签页的handle之后,如何分辨哪个handle才是新开的那个标签页呢?我我们用排除法,先记录当前标签页的handle,之后遍历handle集合,不是当前标签页handle的就是新标签页的handle(前提是只有两个标签页)。
from selenium import webdriver
browser = webdriver.Chrome()
url = '这里填要签到的网址'
browser.ger(url)
username_xpath = 'xxxx'#用户名的xpath
passwd_xpath = 'xxxx'#密码的xpath
login_button_xpath = 'xxxx'#登录按钮的xpath
button1_xpath = 'xxxxx'
button2_xpath = 'xxxxx'
username = 'username'#用户名
passwd = 'passwd'#密码
current_handle = browser.current_window_handle#获取当前标签页的handel
browser.find_element_by_xpath(username_xpath).send_keys(username)#定位用户名输入框,并输入用户名
browser.find_element_by_xpath(passwd_xpath).send_keys(passwd)#定位密码输入框,并输入密码
browser.find_element_by_xpath(login_xpath).click()#找到登录按钮并点击
browser.find_element_by_xpath(button1_xpath).click()#我们假设在点击这个按钮以后,打开了一个新的标签页
all_handles = browser.window_handles#获取所有标签页的handle
for handle in all_handles:#遍历排除,获得新标签页的handle
if handle != current_handle:
rount_handle = handle
browser.switch_to.window(rount_handle)#切换到新标签页
browser.find_element_by_xpath(button1_xpath).click()#在新的标签页上点击button2
第二个问题是如果在当前页面上有弹窗,如何点击弹窗。
未完待续
邮件通知
那么如果由于某种未知的原因签到不成功,我该如何知道我的脚本执行失败了呢?我的方案是,如果执行过程中出现错误,则发送一封邮件到我的信箱
这里用到了smtplib模块,首先安装模块
pip install PyEmail
不会吧不会吧,不会真有人pip install smtplib然后发现报错了吧,反转了,这个人就是我,总之要用以上的命令安装这个模块
以发信方为163邮箱为例,首先需要去163邮箱开启smtp服务,登录163邮箱,在设置里找到这两项打开 然后在下面新增一个授权 注意,我们在脚本里的邮箱登录密码是这里新增授权之后出现的授权码,而不是邮箱登录密码
发邮件的代码模板如下,因为我只是需要在发生错误的时候得到通知,所以只需要最简单的发信功能
import smtplib
def send_error():
HOST = "smtp.163.com"
SUBJECT = "error happens"
TO = "aloha@cat.cn"
FROM = "everyone@behappy.com"
text ="error happened"
BODY = '\r\n'.join((
"From: %s" % "webbrowser",
"TO: %s" % TO,
"subject: %s" % SUBJECT,
"",
text
))
server = smtplib.SMTP()
server.connect(HOST, '25')
server.login(FROM, "passwd")
server.sendmail(FROM, TO, BODY)
server.quit()
这里的host是smtp服务器的地址,subjuect是邮件的标题,text是邮件内容,TO是收件地址,FROM是发件地址,login这行中passwd需要改为163邮箱授权码,相当于一个专用的邮箱登录密码
然后,我们需要在签到代码执行出问题的时候执行以上的函数,这里要用到python的错误处理机制,感兴趣的同学自行了解,代码如下
try:
#签到代码
except Exception as e:
send_error()
这样就可以在捕获到错误时,调用上面写的发邮件的函数