基于selenium模拟第三方账号登录知乎

参考资料:python 用selenium模拟登陆知乎

一、用到的工具

1.python3.6

2.selenium3.141.0

3.Chrome79.0

4.chromedriver79.0。需要注意的是chromedriver的版本需要和Chrome版本对应,这里是下载地址,我采用最粗暴的方法——直接把chromedriver装到python的目录下面,不然可能会报找不到chromedriver的error。

二、模拟登录流程

这里是一个selenium的入门教程。

了解了selenium的大致使用方法后,就可以开始简单模拟登录知乎了。首先注册登录界面

1
2
3
driver=webdriver.Chrome()
url = "https://www.zhihu.com/signin?next=%2F"
driver.get(url)

接下来的工作对于完全不懂html的我就稍微有点难度了,我们需要模拟按登录选项下面第三方登录的“QQ登录”。Chrome的好这时候就体现出来了,在Chrome浏览器的“开发者工具”下可以看到网页源码,并且网页会highlight光标放置的源码对应的区域,这样我们就很容易找到“QQ登录”对应的源码了:
QQ登录)
需要用selenium定位QQ登录按键所在位置,这里是xpath定位方式的一个简单介绍,xpath定位是一种十分灵活的定位方式,在源码中没有class、name的信息时,一般用此定位方式。但也正是由于它太灵活,开始我尝试的各种写法都以失败告终,但我察觉到源码中显眼的”QQ”时,果断采用contain(text())方式,居然成功了:

1
driver.find_element_by_xpath("//div[contains(text(),'QQ')]").click()

此时run一下代码,selenium会模拟到QQ登录的弹窗弹出这一步骤,接下来就是要模拟按“账号密码登录”这一动作,首先需要跳转到弹窗页面:

1
2
handles = driver.window_handles
driver.switch_to.window(handles[1])

同样观察网页源码,发现首先要进入窗口内嵌的登录框架:

1
driver.switch_to.frame('ptlogin_iframe')

对应html源码如下:
登录框架)
上面的switch_to_frame方法具体见这里
模拟点击“账号密码登录”并在登录框里面输入账号密码,关键步骤仍是查看对应html源码,每打开一个新的页面就查看源码,找到所需要的区域:
账号密码登录界面

1
driver.find_element_by_id('switcher_plogin').click()

进入账号密码登录界面后,源码中用户名、密码输入框和login按钮:
用户名密码源码
对应的操作如下:

1
2
3
driver.find_element_by_id('u').send_keys(username)
driver.find_element_by_id('p').send_keys(password)
driver.find_element_by_id('login_button').click()

接下来需要切换回原来的窗口,在这之前,我用time.sleep()方法睡眠了5秒,因为有时候登录比较慢,可能尚未登录窗口就被关闭。

用同样的方法,我又实现了在知乎搜索框中模拟搜索信息的动作:

1
2
3
driver.find_element_by_id('Popover1-toggle').send_keys(content)
time.sleep(1)
driver.find_element_by_xpath("//span[@style='display: inline-flex; align-items: center;']").click()

考虑到加载慢的情况,这里我设置了一定的睡眠时间。

但是我将上述动作封装成API后,模拟出了一点问题:搜索信息窗口出现后很快就自动关闭。我尚未找出问题根源,只能再设置一个睡眠时间将窗口保持住。

三、全部代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import time
from selenium import webdriver

def search_in_zhihu(username:str,password:str,content:str):
driver=webdriver.Chrome()
url = "https://www.zhihu.com/signin?next=%2F"
driver.get(url)
driver.find_element_by_xpath("//div[contains(text(),'QQ')]").click()
# get the window id
handles = driver.window_handles
# switch to the newest window
driver.switch_to.window(handles[1])
driver.switch_to.frame('ptlogin_iframe')
time.sleep(1)
driver.find_element_by_id('switcher_plogin').click()
driver.find_element_by_id('u').send_keys(username)
driver.find_element_by_id('p').send_keys(password)
driver.find_element_by_id('login_button').click()
time.sleep(5)
driver.switch_to.window(handles[0])
driver.find_element_by_id('Popover1-toggle').send_keys(content)
time.sleep(1)
driver.find_element_by_xpath("//span[@style='display: inline-flex; align-items: center;']").click()
time.sleep(20)

if __name__=="__main__":
search_in_zhihu('1234567','wocaonima','nba')
0%