基于Selenium的网站自动登录技术

2024-01-24 08:52卢守东卢明俊
电脑知识与技术 2023年34期
关键词:网络爬虫

卢守东 卢明俊

摘要:网络爬虫的应用十分广泛,其所要完成的任务与所要处理的网站往往差异巨大。针对某些网络爬虫所需要的自动登录功能,介绍一种基于Selenium的解决方案,并通过具体的实例说明有关的编程技术。

关键词:网络爬虫;自动登录;Selenium;Python

中图分类号:TP311      文献标识码:A

文章编号:1009-3044(2023)34-0048-04

开放科学(资源服务)标识码(OSID)

0 引言

目前,网络爬虫方兴未艾,其主要用途就是按照一定的规则从万维网中自动地抓取所需要的有关数据或信息[1]。然后,有些网站出于安全方面或其他因素的考虑,要求登录成功后方可执行相应的功能或访问相应的页面。显然,对于此类网站,作为网络爬虫,就必须具备相应的自动登录功能。在此,将以Windows为系统平台,以Python为编程语言,介绍基于Selenium的网站自动登录技术,供大家参考。

1 Selenium简介

Selenium是一个完全开源的Web自动化工具,主要用于Web应用程序的自动化测试[2]。Selenium测试直接运行在浏览器中,可完全模拟用户的实际操作。与其他测试工具相比,Selenium具有优异的跨平台性与兼容性,可运行于Windows、Linux、Macintosh等系统平台,并支持IE、Chrome、Firefox、Safari、Opera、Edge等浏览器。

在Python中,可借助Selenium库与相应的浏览器驱动,模拟用户在浏览器中的操作,从而实现自动登录功能。在此基础上,可进一步获取有关网页的源代码,并实现网络爬虫的具体功能。

2 关键技术

2.1 Selenium与浏览器驱动的安装

在Python中,Selenium是一个第三方库,必须另行安装,方法之一就是执行命令“pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple”[3]。作為应用实例的开发环境,在此为Python 3.8.18安装了Selenium 4.13.0。

Selenium库安装成功后,还要安装相应的浏览器驱动。各浏览器的驱动是互不相同的,须从各自的地址分别下载。以Chrome浏览器为例,可从地址“https://chromedriver.storage.googleapis.com/index.html”下载与其版本相对应的驱动chromedriver.exe,然后并将其复制到Python的安装目录中[4]。

2.2 浏览器的启动与网页的访问

先从Selenium库导入webdriver模块,再调用该模块的Chrome()函数即可启动Chrome浏览器,并返回相应的浏览器对象。接着,通过浏览器对象调用get()方法,即可根据指定的网址访问相应的网页。为获取当前页面的源代码,可访问浏览器对象的page_source属性。若调用浏览器对象的refresh()或save_screenshot()方法,可刷新当前页面或为当前页面拍照(保存为指定的.png图片)。若调用浏览器对象的maximize_window()或minimize_window()方法,可最大化或最小化浏览器窗口。若调用浏览器对象的close()或quit()方法,则可关闭当前页面或退出浏览器。例如:

from selenium import webdriver

browser=webdriver.Chrome()  #启动Chrome浏览器

browser.maximize_window()  #最大化浏览器窗口

browser.get('https://www.cctv.com')  #访问央视网主页

browser.save_screenshot('cctv.png')  #为页面拍照

print(browser.page_source)  #打印页面源代码

browser.quit()  #退出浏览器

2.3 页面元素的查找与获取

在selenium.webdriver.common.by模块的支持下,通过调用浏览器对象的find_element()或find_elements()方法,可根据元素的ID、Name、CSS类名、Xpath路径、标签名、链接文本等在页面中查找元素,并返回相应的元素对象或元素对象列表。

2.4 页面元素的交互操作

对于所获取到的页面元素对象,可进一步调用其交互方法,执行相应的交互操作。例如,对于文本框对象,可调用send_keys()方法模拟从键盘向其输入指定的内容,或在elenium.webdriver.common.keys模块的支持下模拟输入指定的键盘按键;对于按钮、超链接等对象,可调用click()方法模拟在其上的执行单击操作。

例如,若页面的表单中有一个文本框与一个提交按钮,其id分别为cxtj与ok,为自动在文件框中输入selenium并单击提交按钮,则关键代码如下:

from selenium import webdriver

from selenium.webdriver.common.by import By

browser=webdriver.Chrome()

……

cxtj=browser.find_element(By.ID,'cxtj')

cxtj.send_keys('selenium')

ok=browser.find_element(By.ID,'ok')

ok.click()

……

2.5 等待的设置

页面中某些元素的加载可能需要较长的时间,因此适当的等待有时候是必要的。Selenium支持两种等待方式,即隐式等待与显式等待[5]。隐式等待可设定一个最长的等待时间,在此时间内,会以轮询的方式不断地查找指定的元素,直至找到为止。若超过设定的等待时间依然未能找到指定的元素,则会抛出NoSuchElementException异常。显式等待同样可以设定一个最长的等待时间,但同时要指定相应的检测条件(如指定元素是否出现或可见等)。在此时间内,会以一定的时间间隔进行检测,直至符合条件为止。若超过设定的等待时间依然未能满足指定的条件,则会抛出TimeoutException异常。

隐式等待是全局性的,且用法较为简单,只需调用浏览器对象的implicitly_wait()方法直接设置等待时间(以秒为单位)即可。显式等待则较为灵活,但用法较为复杂,须先调用selenium.webdriver.support.ui模块的WebDriverWait()函数根据指定的浏览器对象与等待时间(以秒为单位)等参数创建一个等待对象,然后再调用等待对象的until()或 until_not()方法设置相应检测条件。至于具体的检测条件,可通过调用selenium.webdriver.support.expected_conditions模块的有关函数加以指定。例如,调用presence_of_element_located()函数可判断指定的元素是否已加载到页面的DOM树中,而调用element_to_be_clickable()函数则可判断指定的元素是否可点击。

例如,为确保id为cxtj元素已被成功加载,可采用显式等待,关键代码如下(最长等待时间为10秒):

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

browser=webdriver.Chrome()

……

wait=WebDriverWait(browser,10)

wait.until(EC.presence_of_element_located((By.ID,'cxtj')))

……

2.6 框架的切换

有些页面中会包含有一些框架(Frame/IFrame) ,从而嵌入了另外的页面。由于Selenium每次只能操作一个页面中的元素,因此要访问框架中嵌入页面的元素,就必须先切换至相应的框架。为此,只需调用浏览器对象switch_to属性的frame()方法即可。例如,为切换至name属性值为login的iframe框架,代码如下:

login=browser.find_element(By.NAME,'login')

browser.switch_to.frame(login)

切换至框架后,便无法继续操作主文档中的元素。此时,若要返回到主文档,可调用浏览器对象switch_to属性的default_content()方法。

2.7 Cookies的处理

Selenium为Cookies的处理提供了全面的支持,通过调用浏览器对象的add_cookie()方法,即可根据名称与值添加指定的Cookie。此外,调用get_cookie()或delete_cookie()方法可根据名称获取或删除指定的Cookie,调用get_cookies()或delete_all_cookies()方法可获取或删除所有的Cookie。例如:

browser.add_cookie({'name':'username','value':'admin'})

browser.add_cookie({'name':'password','value':'12345'})

在此,添加了兩个Cookie,其名称分别为username与password,值则分别为admin与12345。

3 应用实例

3.1 自动登录豆瓣网站并进行查询

豆瓣网站的网址为https://www.douban.com。在浏览器中打开豆瓣网站的主页,并借助开发者工具进行分析,可知其中的登录界面(如图1所示)其实是嵌入到Iframe框架的一个页面,相应的Iframe元素为:

<iframe style="height: 300px; width: 300px;" frameborder="0" src="//accounts.douban.com/passport/login_ popup?login_source=anony"></iframe>

其Xpath路径为“//*[@id="anony-reg-new"]/div/div[1]/iframe”。

登录界面中有“短信登录/注册”与“密码登录”两个标签,后者所对应的元素为:

<li class="account-tab-account on">密码登录</li>

其Xpath路径为“/html/body/div[1]/div[1]/ul[1]/li[2]”。

在“密码登录”界面中,“手机号/邮箱”与“密码”元素的id分别为username与password,而“登录豆瓣”按钮所对应的元素为:

<a class="btn btn-account ">登录豆瓣</a>

其Xpath路径为“/html/body/div[1]/div[2]/div[1]/div[5]/a”。

在登錄成功后所打开的主页面中(如图2所示),“搜索你感兴趣的内容和人...”文本框的name为q,而“搜索”按钮所对应的元素为:

<input type="submit" value="搜索">

其Xpath路径为“//*[@id="db-nav-sns"]/div/div/div[2]/form/fieldset/div[2]/input”。

根据以上分析结果,即可编程实现豆瓣网站的自动登录与信息查询(在此查询关键字“开国大典”) ,代码如下:

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 time

browser=webdriver.Chrome()

browser.maximize_window()

try:

browser.get('https://www.douban.com')

iframe=browser.find_element(By.XPATH,'//*[@id="anony-reg-new"]/div/div[1]/iframe')

browser.switch_to.frame(iframe)

li=browser.find_element(By.XPATH,'/html/body/div[1]/div[1]/ul[1]/li[2]')

li.click()

username=browser.find_element(By.ID,'username')

username.send_keys('180...')  #在此应指定真正的用户名(手机号或邮箱)

password=browser.find_element(By.ID,'password')

password.send_keys('pw...')  #在此应指定真正的密码

button=browser.find_element(By.XPATH,'/html/body/div[1]/div[2]/div[1]/div[5]/a')

button.click()

time.sleep(10)

wait=WebDriverWait(browser,30)

wait.until(EC.presence_of_element_located((By.NAME,'q')))

q=browser.find_element(By.NAME,'q')

q.send_keys('开国大典')

s=browser.find_element(By.XPATH,'//*[@id="db-nav-sns"]/div/div/div[2]/form/fieldset/div[2]/input')

s.click()

time.sleep(5)

browser.save_screenshot('douban.png')

finally:

browser.quit()

运行程序后所生成的图片如图3所示。在右上角,可看到登录用户的昵称,说明已成功登录豆瓣网站。

3.2 自动登录百度账户并进行查询

百度的网址为https://www.baidu.com。在浏览器中打开百度主页,并成功登录百度账户,然后借助开发者工具进行查看与分析,找到BAIDUID与BDUSS这两个Cookie并记录其值。同时,通过元素的检查功能,获知“关键词”文本框与“百度一下”按钮所对应元素的id,分别为kw与su。

根据以上分析结果,即可编程实现百度账户的自动登录(基于Cookie) 与信息查询(在此查询关键字“开国大典”) ,代码如下:

from selenium import webdriver

from selenium.webdriver.common.by import By

import time

browser=webdriver.Chrome()

browser.maximize_window()

browser.get("https://www.baidu.com")

time.sleep(5)

browser.add_cookie({'name':'BAIDUID','value':'DF...'})  #在此应指定真正的BAIDUID值

browser.add_cookie({'name':'BDUSS','value':'5W...'})  #在此应指定真正的BDUSS值

browser.refresh()

time.sleep(5)

keyword=browser.find_element(By.ID,'kw')

keyword.send_keys('開国大典')

button=browser.find_element(By.ID,'su')

button.click()

time.sleep(5)

browser.save_screenshot('baidu.png')

browser.quit()

运行程序后所生成的图片如图4所示。在右上角,可看到登录用户的名称,说明已成功登录百度账户。

4 结束语

网络爬虫的应用十分广泛,其所要完成的任务与所要处理的网站各有不同,具体的实现技术也各种各样。实际的应用表明,如果网络爬虫需要实现网站的自动登录功能,那么基于Selenium的解决方案无疑是颇为灵活、行之有效的。

参考文献:

[1] 网络爬虫_百度百科[EB/OL].[2022-10-20].https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/5162711?fr=ge_ala.

[2] Selenium(WEB自动化工具)_百度百科[EB/OL].[2022-10-18].https://baike.baidu.com/item/Selenium/18266?fr=ge_ala.

[3] 邓劲生,庄春华.实战深度学习:原理、框架及应用[M].北京:清华大学出版社,2021.

[4] 夏敏捷.Python爬虫超详细实战攻略[M].北京:清华大学出版社,2021.

[5] Selenium详细介绍[EB/OL].[2022-10-18].https://blog.csdn.net/weixin_44030265/article/details/127439655#t1.

【通联编辑:谢媛媛】

猜你喜欢
网络爬虫
炼铁厂铁量网页数据获取系统的设计与实现