python爬虫系列6--模拟登陆相关

+ 方式原理

爬虫爬取数据时,有些数据并不能让游客访问到,这时候就需要进行登录,再爬取数据,登录后再爬取的手段很多,但核心都是通过cookie的方式来记录身份信息,因此模拟登录的核心在于对cookie的使用。

参考链接:https://www.cnblogs.com/chenxiaohan/p/7654667.html

(1)直接使用已知cookie访问

简单地说cookie保存在发起请求的客户端中,服务器利用cookie来区分不同的客户端。因为http是一种无状态的连接,当服务器一下子收到好几个请求时,是无法判断出哪些请求是同一个客户端发起的。而“访问登录后才能看到的页面”这一行为,恰恰需要客户端向服务器证明:“我是刚才登录过的那个客户端”。于是就需要cookie来标识客户端的身份,以存储它的信息(如登录状态)。

  当然,这也意味着,只要得到了别的客户端的cookie,我们就可以假冒成它来和服务器对话。这给我们的程序带来了可乘之机。

  我们先用浏览器登录,然后使用开发者工具查看cookie。接着在程序中携带该cookie向网站发送请求,就能让你的程序假扮成刚才登录的那个浏览器,得到只有登录后才能看到的页面。

手动复制浏览器的cookie到程序中访问。

(2)模拟登录后再携带得到的cookie访问

我们先在程序中向网站发出登录请求,也就是提交包含登录信息的表单(用户名、密码等)。从响应中得到cookie,今后在访问其他页面时也带上这个cookie,就能得到只有登录后才能看到的页面。


(3)模拟登录后用session保持登录状态

session是会话的意思。和cookie的相似之处在于,它也可以让服务器“认得”客户端。简单理解就是,把每一个客户端和服务器的互动当作一个“会话”。既然在同一个“会话”里,服务器自然就能知道这个客户端是否登录过。


(4)使用无头浏览器访问

功能强大,几乎可以对付任何网页,但会导致代码效率低。

如果能在程序里调用一个浏览器来访问网站,那么像登录这样的操作就轻而易举了。在Python中可以使用Selenium库来调用浏览器,写在代码里的操作(打开网页、点击……)会变成浏览器忠实地执行。这个被控制的浏览器可以是Firefox,Chrome等,但最常用的还是PhantomJS这个无头(没有界面)浏览器。也就是说,只要把填写用户名密码、点击“登录”按钮、打开另一个网页等操作写到程序中,PhamtomJS就能确确实实地让你登录上去,并把响应返回给你。



具体使用程序来登录的话,方法有2种:简单的网页登录使用后者即可,复杂的使用前者。 https://www.jianshu.com/p/db5878e711d3

1.通过selenium进行浏览器模拟登录(简单粗暴)

2.通过分析登录页面,获取登录接口和提交表单进行登录验证



+ post方式登录网站,需要先将必要信息填充到一个dict中,我怎么知道需要哪些信息填写到dict中呢?我怎么知道需要post的地址url是哪个呢?

要post的url就是有输入用户名和密码框的那个页面的地址;登录豆瓣,用fidder工具查看Method是post的那个包,

打开fidder抓包工具后,浏览器显示“您的连接不是私密连接”原因及解决方案:Fiddler 是一个使用本地 127.0.0.1:8888 的 HTTP 代理,任何能够设置 HTTP 代理为 127.0.0.1:8888 的浏览器和应用程序都可以使用 Fiddler。Fiddler是位于客户端和服务器端的HTTP代理,客户端的所有请求都要先经过Fiddler,然后转发到相应的服务器,反之,服务器端的所有响应,也都会先经过Fiddler然后发送到客户端,基于这个原因,Fiddler支持所有可以设置http代理为127.0.0.1:8888的浏览器和应用程序。

解决方案是Fiddler添加https根证书,Tools - Fiddlers Options-HTTPS-Actions导出根证书放在桌面上,双击证书安装即可,安装之后IE浏览器可以正常访问网页。


+ requests模拟登录京东

import requests

from bs4 import BeautifulSoup

import time



class JDlogin(object):

def __init__(self,un,pw):

self.headers = {'User-Agent':"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",

'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',

'Accept-Encoding':'gzip, deflate, sdch',

'Accept-Language':'zh-CN,zh;q=0.8',

'Connection':'keep-alive',

}

self.session = requests.session()

self.login_url = "http://passport.jd.com/uc/login"

self.post_url = "http://passport.jd.com/uc/loginService"

self.auth_url = "https://passport.jd.com/uc/showAuthCode"

self.un = un

self.pw = pw


def get_authcode(self,url):

self.headers['Host'] = 'authcode.jd.com'

self.headers['Referer'] = 'https://passport.jd.com/uc/login'

response = self.session.get(url, headers = self.headers)

with open('authcode.jpg','wb') as f:

f.write(response.content)

authcode = input("plz enter authcode:")

return authcode


def get_info(self):

'''获取登录相关参数'''

try:

page = self.session.get(self.login_url, headers = self.headers )

soup = BeautifulSoup(page.text)

input_list = soup.select('.form input')


data = {}

data['uuid'] = input_list[0]['value']

data['eid'] = input_list[4]['value']

data['fp'] = input_list[5]['value']

data['_t'] = input_list[6]['value']

rstr = input_list[7]['name']

data[rstr] = input_list[7]['value']

acRequired = self.session.post(self.auth_url, data={'loginName':self.un}).text #返回({"verifycode":true})或({"verifycode":false})


if 'true' in acRequired:

print ('need authcode, plz find it and fill in ')

acUrl = soup.select('.form img')[0]['src2']

acUrl = 'http:{}&yys={}'.format(acUrl,str(int(time.time()*1000)))

authcode = self.get_authcode(acUrl)

data['authcode'] = authcode

else:

data['authcode'] = ''


except Exception as e:

print (e)

finally:

return data

def login(self):

postdata = self.get_info()

postdata['loginname'] = self.un

postdata['nloginpwd'] = self.pw

postdata['loginpwd'] = self.pw

try:

self.headers['Host'] = 'passport.jd.com'

self.headers['Origin'] = 'https://passport.jd.com'

self.headers['X-Requested-With'] = 'XMLHttpRequest'

login_page = self.session.post(self.post_url, data = postdata, headers = self.headers)

print (login_page.text) #若返回{“success”:”http://www.jd.com”},说明登录成功

except Exception as e:

print (e)


if __name__=="__main__":

username = input("plz enter username:")

password = input("plz enter password:")

JD = JDlogin(username,password)

JD.login()


+ Cookie问题

使用requests模拟登陆网站时需要手工构造复杂的模拟请求头,需要抓包分析post数据,可以通过selenium进行模拟登陆,然后将Cookies传入requests,最终用requests进行网站的抓取。优点就是不但规避了“selenium”其本身抓取速度慢的问题(因为仅仅用其作为登陆),又规避了利用requests登陆时需要制作繁琐的Cookies的过程(因为是从selenium直接拿来cookies)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值