python 爬虫解决登录验证问题_python网络爬虫的简单实践——解决无验证模拟登陆问题...

正文开始以前先唠叨几句,一直以来都是自己在网络各大论坛上向大佬们学习东西,如今因为疫情困在家里写毕设,闲余之时也瞎捣鼓了一下,于是想在这里写一点东西,算是自己学习的一个笔记,再一个就是发现网上的教程质量良莠不齐,自己查找资料要花费太多时间去挑选,在这里也是给初学者们做一下整理,大家共同进步!初次创作,如有不善的地方,欢迎大家留言指正!

相信大家对网络爬虫并不陌生,现在许多地方也把网络爬虫称为网络机器人,看起来很高大上,但是要实现简单的爬虫功能,自己用来去网站上爬取一些信息,其实很简单。其中一个简单的例子,教你如何从比亚迪论坛上取想要的数据,下面这篇文章已经讲的很清楚了。

这篇文章有点长,但是对不是非常了解HTML的新手来说算是非常友好的。从HTML获取数据其实很简单,但是我们经常会遇到一些网站,是需要你登陆以后才能看到更多内容的,使用之前的方法,已经无法满足我们的需求。这时候一个思路就是,我们让我们的爬虫程序来模拟我们的登陆行为,然后再去爬取信息,本文在开始之前,假设大家都已经了解如何从HTML获取信息,并且使用python3.x的环境。

根据登陆时是否需要人工验证,我们可以将模拟登陆分为两类。如何让程序通过验证,其中内容较多,完全可以单独来一期讲解,我们这次先讲稍微简单一点的仅需要账号、密码便可登陆的情况。我这里总结出两种方法,各有优劣,大家自己选择自己喜欢的方式。(两个方法的名字都是我自己随便叫的,不要太过纠结于此)想找这种易于操作的网站,最后我把目光放在了学校的教务系统里面。

这里我们以西安交大教务系统为例,向大家实际演练:

方法一:模拟Request方法

在这个方法之中,我们直接向目标地址发送POST请求,其中包含我们登陆所需的信息,服务器在收到我们的POST之后,会将已登陆的信息保存在Cookie或Session中,并且随着应答信息发送回来,这样我们利用Cookie信息,再次访问该网站时,就会被当作已经登陆的对象来处理。

好的,原理大致就是这样的,让我们来看看具体要怎么做吧!首先我们要弄白的时,我们的登陆请求发到哪个地址去了?通常这个地址并不是登陆页面的链接。在登陆页面按F12(有的笔记本是Fn+F12)打开调试窗口,这时候,我们在登陆的界面上随便输一个错误的登陆账号和密码,点击登陆,这时候页面会提示登陆失败,我们在调试窗口上面,点到“network”这一栏,看看在我们登陆的这步中,进行了哪些网络活动。进入Network,查看网络活动

在这个页面中,我们需要找到一个进行POST操作的文件,通常它的名字会带login,但是有些时候,也会简写为l,需要自己区分一下,找一找。我们来看看这个文件都包含了哪些信息。查看POST内容,看到实际POST地址

注意这里的Request URL,这个才是我们POST请求真正送往的地方,因此在编写代码的时候,POST操作的地址应该写这里。我们接着看看,我们到底POST了哪些信息到服务器上。Request Paload中,包含了POST操作所带的所有信息,且是编码后的

我们可以看到上面的“username”对应的就是我们输入的账号,“pwd”其实就是我们的密码,且是经过网页脚本加密过的。我们在自己写POST请求的时候,记住千万要使用编码加密后的密码,那么如何对我们的密码编码呢?我们只需要回到登陆界面随便输入一个账号,并且输入自己的想进行编码的密码,点击登陆,再来查看新的POST文件,里面的密码就对应我们需要的编码后的密码啦!那其他的这些东西是啥呢?其他的这些信息大部分是对登陆的其他的一些设置,直接复制到我们的代码中便可,不同的网站包含的其他信息一般都不同。

另外在一般的网站中操作中,会有一个token信息,是用于防止CFRS跨站请求伪造的方法,它由服务器随机产生,并保存于Session,发送到我们的电脑上,当我们点击登陆时,再通过POST请求,将其发送回服务器,服务器比对token信息,以确认为账户所有者的操作。token信息是动态的,所以我们直接赋值到代码里面是行不通的。所以在进行操作之前,我们要通过一定的手段获取Token信息,本例中没有上述信息,因此不做累述。

好的,知道我们POST信息需要哪些内容,也知道该往哪里POST,我们便可以着手来写我们的代码了:

首先我们需要引入我们所需的库,并定义POST的地址:

import requests

from lxml import html

LOGIN_URL = "https://org.xjtu.edu.cn/openplatform/g/admin/login"

然后定义登陆函数,可以在后面对HTML进行信息爬取:

def main():

session_requests = requests.session() #创建一个session保存登陆状态

# Create payload

payload = {

loginType: 1 #其他信息,一般照着复制过来

username: "" #添加自己的账号

pwd: "" #赋值密码过来

jcaptchaCode: ""

}

# Perform login

result = session_requests.post(LOGIN_URL, data = payload, headers = dict(referer = LOGIN_URL))

执行代码便完成了操作:

if __name__ == '__main__':

main()

总结:方法一访问的速度快,适合高并发运行,但是在在构建payload时较为复杂,特别是在token等随机码的获取方面,有了更多的保护手段。

方法二:模拟浏览器方法

这个方法是利用浏览器驱动程序运行无头浏览器,使用代码控制浏览器进行操作,方法简单,并且难以被反爬虫技术检测。

所谓无头浏览器,即无界面浏览器,目前Chrome,Firefox都推出了无头浏览器模式,在python中,使用selenium或者其扩展库seleniumrequests,均可实现无头浏览器控制。seleniumrequests较selenium,扩展了request的所有功能,在selenium中是没有POST操作的,但是用seleniumrequest却可以实现。

首先,我们需要在python中安装selenium或者seleniumrequest库

python -m pip install selenium

python -m pip install seleniumrequest

然后我们需要下载对应版本的Chrome或Firefox驱动程序,将其放在python文件夹下,接下来我们就可以写代码控制浏览器的运行了。这个方法适合于更加复杂的场景,因此我们可以尝试登陆163邮箱

在这里我们使用Chrome,并且使用selenium库,首先我们引用库函数:

from selenium import webdriver

from selenium.webdriver.chrome.options import Options

接下来就可以设置我们的浏览器驱动了,并且定义我们的登陆信息了:

option = Options()

option.add_argument('--headless') #设置为无头模式,注释这一行,便可看到浏览器如何被操作

driver = Chrome(options=option)

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

USERNAME = ""

PASSWORD = "" #在这里输入自己的用户名和密码

login = "https://mail.163.com/" #此处为登陆页面,不同区模拟request方法,此处之间用登陆的页面

接下啦我们定义登陆函数,通过正则变换找到我们输入信息的地方:

def user_login(account, password,url):

driver.get(url)

time.sleep(2) #记住,每进入一个新页面,都需要暂停一段时间,等待浏览器渲染js文件

driver.find_element_by_xpath("//div[@id='mainbg']/div[3]/div/div[3]/div[4]/div[1]/div/iframe/html/body/div[2]/div[1]/div[2]/form/div/div[1]/div[2]/input").send_keys(account)

driver.find_element_by_xpath("//div[@id='mainbg']/div[3]/div/div[3]/div[4]/div[1]/div/iframe/html/body/div[2]/div[1]/div[2]/form/div/div[3]/div[2]/input[2]").send_keys(password)

driver.find_element_by_xpath("//div[@id='mainbg']/div[3]/div/div[3]/div[4]/div[1]/div/iframe/html/body/div[2]/div[1]/div[2]/form/div/div[8]/a").click()

#在HTML中找到相应输入框和按钮的位置,然后执行相应操作

接下来就可以定义主函数,进行我们需要的操作了:

def main():

user_login(USERNAME,PASSWORD) #登陆

time.sleep(2)

#do whatever you want

最后执行我们的主函数便可:

if __name__ == '__main__':

main()

总结:方法简单,并且难以被反爬虫技术检测,但是渲染和启动都较为耗时,不适合高并发执行

最后再唠叨一下,爬虫和反爬虫一直都在相互对抗的关系中共同进步,所以我们经除会看到新的反爬虫技术的出现,导致原有的方法无法使用,也会因为新的爬虫技术的出现,促进反爬虫技术的进度,无论对哪一方更感兴趣,都应知己知彼。

  • 0
    点赞
  • 3
    收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值