反扒机制代理操作及验证码的识别
反扒机制:代理操作
代理操作:
-
在爬虫中,所谓的代理指的是什么?
- 就是代理服务器
-
代理服务器的作用:
- 就是用来转发请求和响应的
-
在爬虫中为什么需要使用代理服务器:
- 如果我们的爬虫对服务器短时间内发出高频请求。那么服务器检测到这样一个异常请求,就会将该请求的对应设备IP禁掉,这样就无法给服务器发请求获取数据了!
- 如果ip被禁,我们就可以使用代理服务器进行请求转发,破解ip被禁的反爬机制。因为使用代理后,服务器端接受到的请求对应的ip地址就是代理服务器而不是我们真正的客户端的。
-
代理服务器分为不同的匿名度:
- 透明代理:如果使用了该形式的代理,服务器端知道你使用了代理机制也知道你的真实ip。
- 匿名代理:知道你使用代理,但是不知道你的真实ip
- 高匿代理:不知道你使用了代理也不知道你的真实ip
- 代理的类型
- https:代理只能转发https协议的请求
- http:转发http的请求
- 代理服务器:
- 快代理
- 西祠代理
- goubanjia
- 代理精灵(推荐):http://http.zhiliandaili.cn/)-
封装一个代理池
from lxml import etree #以下这网址就是你用代理。代理给你的 url = 'http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=4&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2' page_text = requests.get(url,headers=headers).text tree = etree.HTML(page_text) proxy_list = tree.xpath('//body//text()') http_proxy = [] #代理池 for proxy in proxy_list: dic = { 'http':proxy } http_proxy.append(dic) http_proxy 结果; [{'http': '58.243.28.218:33503'}, {'http': '114.106.151.234:10566'}, {'http': '114.252.50.79:11484'}, {'http': '106.7.4.131:28803'}]
对西祠代理发起一个高频的请求,让其将我本机ip禁掉
url = 'https://www.xicidaili.com/nn/%d' ips = [] for page in range(1,11): new_url = format(url%page) page_text = requests.get(url=new_url,headers=headers).text tree = etree.HTML(page_text) #在xpath表达式中不可以出现tbody标签 tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:] for tr in tr_list: ip = tr.xpath('./td[2]/text()')[0] ips.append(ip) print(len(ips))
使用代理机制破解ip被封的效果
#代理池对应的代码 url = 'http://ip.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=29&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2' page_text = requests.get(url,headers=headers).text tree = etree.HTML(page_text) proxy_list = tree.xpath('//body//text()') http_proxy = [] #代理池 for proxy in proxy_list: dic = { 'https':proxy } http_proxy.append(dic) #url模板 url = 'https://www.xicidaili.com/nn/%d' ips = [] for page in range(1,11): new_url = format(url%page) #让当次的请求使用代理机制,就可以更换请求的ip地址 #requests模块有代理参数!! page_text = requests.get(url=new_url,headers=headers,proxies=random.choice(http_proxy)).text tree = etree.HTML(page_text) #在xpath表达式中不可以出现tbody标签 tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:] for tr in tr_list: ip = tr.xpath('./td[2]/text()')[0] ips.append(ip) print(len(ips))
-
验证码的识别
-
基于线上的打码平台识别验证码
-
打码平台
-
1.超级鹰(使用):
http://www.chaojiying.com/about.html
- 1.注册【用户中心的身份】
- 2.登录(用户中心的身份)
- 1.查询余额,请充值
- 2.创建一个软件ID(899370)
- 3.下载示例代码
-
2.云打码
-
3.打码兔
这是超级鹰的示例代码 import requests 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()
然后自己写个函数实例化超级鹰
def tranformImgCode(imgPath,imgType): chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370') im = open(imgPath, 'rb').read() return chaojiying.PostPic(im,imgType)['pic_str'] print(tranformImgCode('./a.jpg',1902)) 7261
模拟登录
- 流程:
- 对点击登录按钮对应的请求进行发送(post请求)
- 处理请求参数:
- 用户名
- 密码
- 验证码
- 其他的防伪参数
#这里别忘记带上cookie!!! session = requests.Session() #识别验证码 url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx' page_text = session.get(url=url,headers=headers).text #解析验证码图片的地址 tree = etree.HTML(page_text) img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0] #将验证码图片保存到本地 img_data = session.get(img_src,headers=headers).content with open('./code.jpg','wb') as fp: fp.write(img_data) #识别验证码 code_text = tranformImgCode('./code.jpg',1902) print(code_text) login_url ='https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx' data = { '__VIEWSTATE': '4iQUDYGYp480//d8dSe+k037Ut9ijESlrJJLPgCEsA+C4EAmEQV4h+p/G4sKwsGz2mFdGeIE+TS8T6Gru2w14b4n2qfsxdeB4caV4zXWhLNTbDM9m/heuikk8S4=', '__VIEWSTATEGENERATOR': 'C93BE1AE', 'from': 'http://so.gushiwen.org/user/collect.aspx', 'email': 'www.zhangbowudi@qq.com', 'pwd': 'bobo328410948', 'code': code_text,#动态变化 'denglu': '登录', } #对点击登录按钮发起请求:获取了登录成功后对应的页面源码数据 page_text_login = session.post(url=login_url,headers=headers,data=data).text with open('./gushiwen.html','w',encoding='utf-8') as fp: fp.write(page_text_login)
-
发现上图参数中有2组乱码参数。
-
在请求参数中如果看到了一组乱序的请求参数,最好去验证码这组请求参数是否为动态变化。
-
处理:
- 方式1:常规来讲一半动态变化的请求参数会被隐藏在前台页面中,那么我们就要去前台页面源码中取找。
- 方式2:如果前台页面没有的话,我们就可以基于抓包工具进行全局搜索。