0


【selenium/北邮/信息门户/反反爬】selenium实现——北京邮电大学 信息门户 反反爬登录

反爬机制壹——js控制的登录逻辑

没有表单form,根本不可能点击确认提交

# from urllib.request import urlopen  import requests  
  
url ="http://my.bupt.edu.cn/"  
header ={"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}  
para ={"service":"http://my.bupt.edu.cn/"}  
resp = requests.get(url, params=para)  
  
string = resp.text  
  
print(string)  
resp.close()

解决思路

  • 用selenium
  • 先get登录页面
options = FirefoxOptions()  
options.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0"')
web = Firefox(options=options)# web = Chrome() 用Chrome也可以,但对应的options也要换成ChromeOptions
web.get("http://my.bupt.edu.cn/")
  • 尝试使用find_element(By.XPATH, “//*”)去寻找对应元素
<ahref="javascript:;"i18n="login.type.password"class="">密码登录</a>
login_pwd = web.find_element(By.XPATH,"//*[@id="content-title"]/a[2]")
  • 但是会出现无法定位

反爬机制贰——以文档形式嵌套的HTML网页

为什么找不到目标超链接元素?

  • 我们先看网页代码,怎么会有两个html标签?
<!DOCTYPEhtml><html>
    ......
    <body><iframeid="loginIframe"src="/authserver/cas/login-normal.html">
        #document
            <!DOCTYPEhtml><htmllang="en">
            ....
            </html></iframe></body></html>
  • 究竟怎么绘世呢?
  • 如果我们尝试打印所有元素的class,我么会发现嵌套在iframe里面的html的标签的类根本不出现在find_elements中
l = web.find_elements(By.XPATH,"//*")for ele in l:print(ele.get_attribute('class'))
  • 再细看,这里的src是啥
<iframeid="loginIframe"src="/authserver/cas/login-normal.html">

解决思路

  • 由此,我们发现找不到元素的根本原因在于—— - 网站通过html的JavaScript访问内嵌html文件,取出了静态页面- 再把所需要展示的元素通过别的手段取出,填充到静态页面中- 在DevTools可视化界面中,我们会默认文件里的内容也是网页的一部分- 但实际上无论是直接在DevTools上直接拷贝,还是selenium中访问,都不会认为这个文件里面的内容是网页
  • 实际上就是这种范式
<html><head>...</head><body><frameid=xxx,name=***><html><span>xx</span><p>......</p><div>x8888</div></html></frame></body></html>

此处参考:

python selenium获取html网页中嵌套的 frame/iframe中的html内容方法

  • 做法: 先转到所在iframe中,再去搜索
iframe = web.find_element(By.XPATH,"//*[@id='loginIframe']") 

web.switch_to.frame(iframe)
  • 现在再找,也不会报错了
login_pwd = web.find_element(By.XPATH,"//a[@i18n='login.type.password']")

反爬机制叁——href为空的超链接元素

  • selenium报错,不能点击
selenium.common.exceptions.ElementNotInteractableException: Message: Element <a href="javascript:;"> could not be scrolled into view
  • 为啥呢?

解决思路

  • 由于超链接为空(javascript:; ),所以这里大概是用js代码监听点击事件来控制页面显隐
  • 这几个超链接所在div有id,因此,我们可以先从此入手
<divclass="content-title auto"id="content-title"><ahref="javascript:;"class="active"i18n="login.type.qrcode">扫码登录</a><ahref="javascript:;"i18n="login.type.password">密码登录</a><ahref="javascript:;"i18n="login.type.sms">短信登录</a></div>
  • 在DevTools的network中搜索content-title,发现有且仅有一个与之相关的函数
//登录方式切换$('#content-title a').on('click',function(){var index =$(this).index();var length =$('#content-title a').length;
            localStorage.loginType = index
            for(var x =0; x < length; x++){if(x === index){$('#content-con div.content-con-box').eq(index).show()$('#content-title a').eq(index).addClass('active')}else{$('#content-con div.content-con-box').eq(x).hide()$('#content-title a').eq(x).removeClass('active')}if(index ===0)initQR();}})

从show, hide, active来看,很显然,就是用这个来控制页面显隐的

  • 结合前人的经验来看,我们需要以js代码的形式来点击这个超链接
login_pwd = web.find_element(By.XPATH,"//a[@i18n='login.type.password']")
web.execute_script("arguments[0].click();", login_pwd)

此处参考:

Selenium模拟用户点击爬取javascript void(0)的超链接

  • 看起来似乎已经结束了?

反爬机制肆——加载时间

仍然没有反应?

  • 难道一切的努力都已经白费? - 非也

解决思路

  • 只是切换完iframe之后还需要一段时间加载资源等,需要用time.sleep()来等等 😉
我知道你很急,但你先别急 
iframe = web.find_element(By.XPATH,"//*[@id='loginIframe']") 

web.switch_to.frame(iframe)

time.sleep(2)  

login_pwd = web.find_element(By.XPATH,"//a[@i18n='login.type.password']")  

web.execute_script("arguments[0].click();", login_pwd)
  • 这样子,就大功告成了
  • 网络状况良好的条件下,最低等待时间(time.sleep(n))大约在0.15s左右
反爬,终究是有极限的!

尾声——登录实现

time.sleep(0.2)  
username = web.find_element(By.XPATH,'//*[@id="username"]')  
password = web.find_element(By.XPATH,'//*[@id="password"]')  
submit_btn = web.find_element(By.XPATH,'//*[@value="账号登录"]')  
  
username.send_keys(usr)  
password.send_keys(pwd)  
submit_btn.click()

如今,类似的反爬机制已经大量应用于各个网站的登录界面,看似轻巧的设计却需要诸多时间去反制,站在巨人的肩膀上,我也花费了不少的时间才能走到这一步

不过有一说一,这很令人开心 😃


本文转载自: https://blog.csdn.net/weixin_50750441/article/details/126809295
版权归原作者 小助手牧濑红莉栖 所有, 如有侵权,请联系我们删除。

“【selenium/北邮/信息门户/反反爬】selenium实现——北京邮电大学 信息门户 反反爬登录”的评论:

还没有评论