使用万能钥匙 Selenium 搞定一切登录

806次阅读
没有评论

Selenium, 大名鼎鼎的Web自动化测试工具,可以跨越Linux、Windows、macOS等平台使用,支持Java、Python、C#、Ruby等多种语言编程,为Web系统自动化测试带来强大支持。通过WebDriver方便操作浏览器,这也给爬虫界带来十分的便利。它可以被称为爬虫登录的万能钥匙,可以横扫一切网站的登录。

使用万能钥匙

如果说,完全用Python代码模拟登录是我们智力的体现,那么选择 Selenium 就是我们的智慧所在。没办法,用它就是一个字儿:倍儿爽!

1. Selenium 登录获取cookies的流程

利用这把万能钥匙的流程大致如下:

  1. 使用Selenium WebDriver 打开浏览器;
  2. 如果没有验证码,可以通过代码输入用户名和密码并点击登录按钮;如果需要人工输入变态的验证码,就让WebDriver sleep一定时间,等待人工输入完成;
  3. 登录后获取cookies,并保存到文件或数据库。

如果上述过程是不需要人工输入验证码的,可以使用 Headless Chrome ,它能在无桌面环境下运行,比如Linux 服务器上一般是没有安装桌面环境的。

获取cookies以后,我们可以继续用webdriver抓取数据页面,这适合于异步加载的页面的抓取;或者把cookies导入到requests的session,利用requests抓取数据页面,这适合于非异步加载的页面。

2. Selenium 登录的实现

按照上面的思路,我们实现两个登录的过程,一个需要验证码,一个不需要验证码。

不需要人工输入验证码的登录:

def login_auto(login_url, username, password,
               username_xpath, password_xpath,
               submit_xpath, cookies_file, browser=None):
    if browser is None:
        options = webdriver.ChromeOptions()
        # chrome在系统PATH时,可以不指定 binary_location 
        # options.binary_location = ‘/usr/bin/google-chrome’
        options.add_argument('headless')
        options.add_argument('window-size=1200x600')
        browser = webdriver.Chrome(chrome_options=options)
    browser.maximize_window()
    browser.get(login_url)
    time.sleep(9) # 等登录加载完成
    browser.find_element_by_xpath(username_xpath).send_keys(username)
    browser.find_element_by_xpath(password_xpath).send_keys(password)
    browser.find_element_by_xpath(submit_xpath).send_keys(Keys.ENTER)
    time.sleep(9) # 等登录加载完成
    cookies = browser.get_cookies()
    print(cookies)
    save_cookies(cookies, cookies_file)

这个login_auto()函数,使用了headless的chrome,最大化窗口的目的是让整个页面都显示出来,如果默认大小,微博登录页面就不显示登录输入框,自动填写用户名时会保存。

sleep的目的是等待加载登录页面完成,还是微博,它的登录跳转比较费时间,不能一下子加载完成,必须等待。

登录完成我们就可以得到cookies了。通过webdriver的get_cookies()得到的cookies是一个列表,每个元素是一个字典,包含了domain, expiry, name, value等等字段。

最后我们把得到的cookies保存为文件,这里用pickle直接序列化到硬盘,这个cookies就可以被爬虫使用抓取数据了。

需要人工输入验证码的登录

def login_manually(login_url, cookies_file, browser=None):
    # 既然是手动,这里就不自动填写用户名和密码了
    if browser is None:
        browser = webdriver.Chrome()
    browser.get(login_url)
    time.sleep(30) # 给自己多了点时间输入用户名、密码、验证码
    cookies = browser.get_cookies()
    print(cookies)
    save_cookies(cookies, cookies_file)

需要人工介入的登录,就是让程序自动打开一个浏览器,然后人工输入登录信息完成登录,最后程序保存cookies的过程。

这里可不能用headless的Chrome哦,不然你看不到浏览器窗口无法输入,哈哈哈~

当然,你也可以让程序自动填写用户名、密码,类似login_auto()那样实现,小猿们有兴趣的话可以添加这部分功能。

3. Selenium 登录后的cookies的使用

用Selenium保存的cookies,可以继续给WebDriver使用,去抓取复杂的异步加载(AJAX)的网页,也可以给requests使用快速加载非异步页面。为此,我们实现两个不同的加载函数:

加载cookies到WebDriver

def load_to_browser(cookies_file, browser=None):
    with open(cookies_file, 'rb') as f:
        cookies = pickle.load(f)
    if browser is None:
        browser = webdriver.Chrome()
    for cookie in cookies:
        browser.add_cookie(cookie)
    return browser

保存时用的是pickle序列化到硬盘,读取到内存时同样使用pickle, 把cookies放入WebDriver很简单,把cookies逐个用add_cookie()放入即可。

加载cookies到requests的session

requests的cookies是用RequestsCookieJar这个类管理的,它的结构和WebDriver 的cookies不太一样,它只需要name, value即可,所以加载到requests有些不同:

def load_to_requests(cookies_file, session=None):
    with open(cookies_file, 'rb') as f:
        cookies = pickle.load(f)
    if session is None:
        session = requests.Session()
    for cookie in cookies:
        session.cookies.set(cookie['name'], cookie['value'])

4. Selenium 登录实战: 微博、哔哩哔哩、知乎的登录

微博有时候是不需要输入验证码的,此时就可以自动化登录。幸运的是,我的账号在我机器上就不需要输入验证码,省的我费劲去找一个不需要验证码的网站(现如今真的很难找啊~) 好了,看代码:

login_url = 'https://weibo.com/'
username_xpath = '//input[@id="loginname"]'
password_xpath = '//input[@name="password"]'
submit_xpath = '//a[@action-type="btn_submit"]'
username = 'your-username'
password = 'your-password'
login_auto(login_url, username, password, username_xpath, password_xpath, submit_xpath, 'z-weibo.cookies')
 ```

而哔哩哔哩、知乎都需要手动解锁验证码,那我们就用人工介入的模式登录:
```python
login_url = 'https://passport.bilibili.com/login'
login_manually(login_url, 'z-bilibili.cookies')

借用login_manually()函数是不是非常的简单,同样的知乎的也很简单:

login_url = 'https://passport.bilibili.com/login'
login_manually(login_url, 'z-zhihu.cookies')

出乎意料的是,登录知乎出现了问题,报了一个错误:Missing argument grant_type。网上有人说是Chrome版本问题,降低版本后就可以了。

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:wuyou2023-01-15发表,共计3642字。
新手QQ群:570568346,欢迎进群讨论 Python51学习