1.模拟登录
用于爬取某些用户的信息。
2.对人人网进行模拟登录的分析
2.1 弄清人人网登陆的流程
-
输入用户名、密码、验证码(验证码需要输入错误三次密码才会出现)
-
找到“登录”button
-
右键——检查——勾选“preserve log”(保留日志)
-
点击登录按钮
-
在捕获到的数据包中点击“login”对应的数据包查看相关详细信息
-
发现这是一个post请求,同时post请求中会携带之前录入的登录信息(用户名,密码,验证码……)
2.2 验证码流程
- 验证码的识别,获取验证码图片的文字数据
- 对post请求进行发送(处理请求参数)
- 对相应数据进行持久化存储
2.3 一些注意事项
①人人网的注册需要在搜索页面进行点击,登陆页面中的注册页面总是跳转不成功
②.因为使用了超级鹰的识别验证码功能,但他返回的是一个json格式的对象
return r.json()
这里就要使用关键值对应得方法对验证码信息进行提取:
可以看到我下载的python版本中识别出的的验证码信息保存在“pic_str”中
获取方式也就是result[“pic_str”]
这里补充一下关于json中相应数据的提取方式:
代码
import json
#json string:
s = json.loads('{"name":"test", "type":{"name":"seq", "parameter":["1", "2"]}}')
print(s)
print(s.keys())
print(s["name"])
print(s["type"]["name"])
print(s["type"]["parameter"][1])
输出:
{
'name': 'test', 'type': {
'name': 'seq', 'parameter': ['1', '2']}}
dict_keys(['name', 'type'])
test
seq
2
3.登录代码实现
#!/usr/bin/env python
# coding:utf-8
import requests
import json
from lxml import etree
from hashlib import md5
#封装识别验证码图片的函数
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {
'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
#UA伪装
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.11 Safari/537.36'
}
#1.对验证码图片进行捕获和识别
url='http://www.renren.com/SysHome.do'
page_text=requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
#2.找到验证码图片所在的层次
code_img_src=tree.xpath('//*[@id="verifyPic_login"]/@src')[0]
code_img_data=requests.get(url=code_img_src,headers=headers).content
with open('./code.jpg',"wb") as fp:
fp.write(code_img_data)
chaojiying = Chaojiying_Client('your account', 'password', 'softwareID') # 用户中心>>软件ID 生成一个替换 96001
im = open('./code.jpg', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
codeType=1006
result=chaojiying.PostPic(im,codeType)
icode = result["pic_str"]
#3.post请求的发送(模拟登录)
login_url='http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2021211039757'
data={
"email":"your email",#这里填写自己的email
"icode":icode,
"origURL":"http://www.renren.com/home",
"domain":"renren.com",
"key_id":"1",
"captcha_type":"web_login",
"password":"网页检查工具中可以自动查看",
"rkey":"相应的login界面中可以找到这些参数",
"f":"http%3A%2F%2Fwww.renren.com%2F976289988%2Fprofile",
}
response=requests.post(url=login_url,headers=headers,data=data)
#print(response.status_code)
#这里的请求状态查询,如果结果是200,说明请求成功
输出:
结果为200,说明登陆成功!
4.模拟登录中的cookie操作
http/https协议特性:无状态
意思即为服务器端是不会保留用户的登陆状态的,如果直接访问登陆后的用户界面的url,得到的将还是原来的登陆界面,所以我们就需要cookie存储状态。
4.1 cookie
由服务器端所创建,存储在code中,用来让服务器端记录客户端的相关状态。
所以我们就可以在对应的profile请求中找到cookie,这意味着这次的请求是在已登录状态下的请求:
4.2 处理cookie的两种方式
① 手动处理:从抓包工具中获得cookie值,将该值写入headers,但这种方法不适用于如果cookie是动态变化的情况。
② 自动处理:
- 第一次登陆请求post时,由服务端所创建
- 使用session会话对象
作用:
- Ⅰ.可以进行请求的发送
- Ⅱ.如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中
流程:
- 1)创建一个seesion对象:session=request.Session
- 2)使用session对象进行模拟登录post请求的发送(cookie就会被存储在session中)
- 3)session对象对个人主页对应的get请求进行发送(携带cookie)
代码:
#!/usr/bin/env python
# coding:utf-8
import requests
import json
from lxml import etree
from hashlib import md5
#封装识别验证码图片的函数
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {
'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
#0.创建一个session对象
session= requests.Session()
#UA伪装
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.11 Safari/537.36'
}
#1.对验证码图片进行捕获和识别
url='http://www.renren.com/SysHome.do'
page_text=requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
#2.找到验证码图片所在的层次
code_img_src=tree.xpath('//*[@id="verifyPic_login"]/@src')[0]
code_img_data=requests.get(url=code_img_src,headers=headers).content
with open('./cookieImg.jpg',"wb") as fp:
fp.write(code_img_data)
chaojiying = Chaojiying_Client('your account', 'password', 'softwareID') # 用户中心>>软件ID 生成一个替换 96001
im = open('./cookieImg.jpg', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
codeType=1006
result=chaojiying.PostPic(im,codeType)
icode = result["pic_str"]
print(icode)
#3.post请求的发送(模拟登录)
login_url='http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2021211039757'
data={
"email":"your email",#这里填写自己的email
"icode":icode,
"origURL":"http://www.renren.com/home",
"domain":"renren.com",
"key_id":"1",
"captcha_type":"web_login",
"password":"网页检查工具中可以自动查看",
"rkey":"相应的login界面中可以找到这些参数",
"f":"http%3A%2F%2Fwww.renren.com%2F976289988%2Fprofile",
}
#4.使用seesion对象进行post请求的发送
response=session.post(url=login_url,headers=headers,data=data)
print(response.status_code)
detail_url='http://www.renren.com/976289988/profile'
detail_page_text=session.get(url=detail_url,headers=headers).text
with open('xixi.html','w',encoding='utf-8') as fp:
fp.write(detail_page_text)
pass
print("用户信息爬取成功!")
输出:
爬取的网页代码可以展现,说明爬取成功