反反爬-课上实验
1. cookie登录获取信息
使用cookies进行登录,然后获取到登录信息:只适用于一般情况,一般网站都不能成功
import requests
from lxml import etreeheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36','Cookie': 'Hm_lvt_2a615a64db40efaf71fce02a85214e10=1730975070; HMACCOUNT=F89A075820B0EAF1; acw_tc=0a472f8e17309752875908289e00a9aaac794bd6bdaf51f4b51bc230607629; a70c_2132_saltkey=22i89ch0; a70c_2132_lastvisit=1730971687; a70c_2132_sendmail=1; a70c_2132_onlineusernum=52; Hm_lpvt_2a615a64db40efaf71fce02a85214e10=1730975291; a70c_2132_sid=MzHsIM; a70c_2132_lastact=1730975387%09member.php%09logging; a70c_2132_auth=ccd7Aibzth3NoGGrt6ch8%2BnTSZI%2BHa1TB0tMPyEvAKcycnxKREksJhnRGCVkNPpgU7f%2FQYl3uZM6Rkq851oUOoQPWd8j'
}
response = requests.get('https://www.txrjy.com/forum.php',headers=headers)
print("停不停" in response.text)
html = etree.HTML(response.text)
username = html.xpath('//*[@id="um"]/div[2]/strong/a/text()')[0]
print('用户名',username)
2.构建session字典
保持会话信息,防止反爬检查
import requests
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
}
form_data = {'username': '停', # 用户名'password': '123456', # 密码'quickforward': 'yes', # 对普通用户隐藏的字段,该值不需要用户主动设定'handlekey': 'ls' # 对普通用户隐藏的字段,该值不需要用户主动设定
}session = requests.Session() # 使用requests的session来保持会话状态
session.post('https://www.txrjy.com/member.php?mod=logging&action=login&loginsubmit=yes',headers=headers,data=form_data
)
response = session.get('https://www.txrjy.com/forum.php').text
print('username' in response)
3.JWT
在网页爬虫过程中,遇到JWT(JSON Web Token)是一种常见的身份验证方式。JWT是一种基于JSON的开放标准(RFC 7519)用于在各方之间传输信息。它可以在客户端与服务器之间安全地传递信息,因为它可以被签名和加密。以下是关于JWT的一些关键点以及如何处理它的建议:
JWT的工作原理:
结构:JWT由三个部分构成,它们用点(
.
)分割:
- Header(头部):通常包含签名算法的信息,比如HMAC SHA256或RSA。
- Payload(负载):包含声明(claims),即传递的数据,比如用户信息和token的过期时间。
- Signature(签名):用于验证消息在传输过程中未被更改。
一个典型的JWT结构看起来像:
xxxxx.yyyyy.zzzzz
用法:
- JWT通常用于身份验证。客户端在登录后从服务器获取一个JWT,并在后续请求中将这个JWT发送到服务器(通常在HTTP请求头的
Authorization
字段中),以证明其身份。- 服务器通过验证JWT来检查请求者的身份和权限。
爬虫面临的挑战与应对策略:
获取JWT:
- 初始登录:你可能需要模拟用户登录过程来获取JWT。这通常涉及提交用户名和密码并处理服务器返回的信息。
- 解析响应:在模拟登录成功响应中,查找JWT的位置,通常在响应的Cookies或JSON响应体中。
维持Session:
- 一旦获取到JWT,你需要在后续的每个请求中包含这个JWT,通常在请求头中设置
Authorization: Bearer <token>
。- 注意JWT的有效期,许多JWT具有过期时间。如果JWT过期,你可能需要重新进行登录流程来获取新的JWT。
处理过期和刷新令牌:
- 如果服务器提供“刷新令牌”的机制,利用刷新令牌自动获取新的JWT,而不需要再次登录。
- 实现令牌的生命周期管理,确保在令牌过期前自动刷新或重新获取令牌。
注意事项:
- 合法使用:确保遵守目标网站的服务条款和法律法规。
- 隐私和安全:妥善处理你的凭证和JWT,避免泄露。
- 技术挑战:某些网站采用复杂的验证机制(比如CAPTCHA和其他反爬机制),在这些情况下,普通爬虫技术可能难以持久工作。
4.JWT实战
发现数据包:
存在Authorization:
import requestsheaders = {"Accept": "application/json, text/plain, */*","Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",# "Authorization": "jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzMxMDIyMTk2LCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsIm9yaWdfaWF0IjoxNzMwOTc4OTk2fQ.ePhgUAhxAgsfiNM1JS7YLnqwQDSFwYUlxuTWHs7Fp80","Cache-Control": "no-cache","Connection": "keep-alive","Pragma": "no-cache","Sec-Fetch-Dest": "empty","Sec-Fetch-Mode": "cors","Sec-Fetch-Site": "same-origin","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36","sec-ch-ua": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "\"Windows\""
}
url = "https://login3.scrape.center/api/book/"
params = {"limit": "18","offset": "0"
}
response = requests.get(url, headers=headers, params=params)print(response.json())
进行Authorization删除和不删除结果对比,发现存在JWT,同时Authorization是关键字段
不删除:
删除:
通过几次重新登录对比Authorization,发现Authorization关键字段是变化的,尝试构建Authorization
既然是随登录改变,先去登录信息看,发现:
有理由怀疑它是Authorization关键字段,尝试token构造成Authorization字段,测试一下能否获取到数据:
import requests
import jsonheaders = {"Accept": "application/json, text/plain, */*","Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8","Cache-Control": "no-cache","Connection": "keep-alive","Content-Type": "application/json;charset=UTF-8","Origin": "https://login3.scrape.center","Pragma": "no-cache","Sec-Fetch-Dest": "empty","Sec-Fetch-Mode": "cors","Sec-Fetch-Site": "same-origin","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36","sec-ch-ua": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "\"Windows\""
}
url = "https://login3.scrape.center/api/login"
data = {"username": "admin","password": "admin"
}
data = json.dumps(data, separators=(',', ':'))
response = requests.post(url, headers=headers, data=data)# print(response.json())
params = {"limit": "18","offset": "0"
}
session = requests.Session()
session.headers.update(headers)
session.headers['Authorization'] = "jwt " + response.json()['token']
# print(session.headers)
response1 = session.get('https://login3.scrape.center/api/book/',params=params)
print(response1.json())