爬虫 第九讲 反爬的策略

一、JS反爬

1.环境搭建

安装node.js

下载网站:https://nodejs.org/en/download/
参考网站:https://blog.csdn.net/qq_41465646/article/details/107656044

安装js代码调试工具

发条js代码调试工具

安装 PyExecJs模块

pip install PyExecJs -i https://pypi.douban.com/simple

2.JS中常见的算法

• 线性散列MD5算法
• 对称加密DES/AES算法
• 非对称加密算法RSA
• base64加密算法

MD5算法

MD5是一种被广泛使用的线性散列算法,可以产出一个128位(16字节)的散列值(hash value),用于确保信息传输完整的一致性。且MD5加密之后产生的是一个固定长度(32位或16位)数据
https://cdn.bootcdn.net/ajax/libs/blueimp-md5/1.0.1/js/md5.js

DES/AES算法

DES对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密钥(称为对称密码),是一种对称加密算法

AES和DES的区别

• 加密后密文长度不同
• DES加密后密文长度是8的整数倍
• AES加密后密文的长度是16的整数倍
• 安全度不同
• 一般情况下DES足够安全
• 如果要求高可以使用AES
• DES和AES切换只需要修改CryptoJS.DES =>CryptoJS.AES

RSA算法

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
非对称加密需要2个密钥
• 公开密钥(publickey:公钥)
• 私有密钥(privatekey:私钥)
• 公钥和私钥是一对

base64加密算法

base64是一种用64个字符来表示任意二进制数据的方法。
base64使用 A–Z a–z 0–9 + / 这64个字符实现对数据的加密

3.案例演示

微信公众平台:https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=40987134
steam平台:https://store.steampowered.com/login/?redir=&redir_ssl=1
完美世界:https://passport.wanmei.com/login?location=L3NhZmUv

二、字体反爬

1.什么是字体反爬?

就是网页的制作者,它在发布他网页数据的时候。将其中一部分的字体变成乱码。即使你把网页的数据爬取下来,你也获取不到真实数据的样貌。这样就达到了一个反爬虫的目的

2.如何解决字体反爬?

• 1 下载.ttf文件
• 2 将.ttf文件转换成xml文件
• 3 分析字体规律找到映射关系
测试网站
https://club.autohome.com.cn/bbs/thread/665330b6c7146767/80787515-1.html

三、验证码图片反爬

import requests
from hashlib import md5
from PIL import Image
from selenium import webdriver
import time
from selenium.webdriver import ActionChains

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()


# chaojiying = Chaojiying_Client('Jerry1234 ', '123456', '914400')  # 用户中心>>软件ID 生成一个替换 96001
# im = open('code2.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
# print(chaojiying.PostPic(im, 9004)['pic_str'])


driver = webdriver.Chrome()
# 加载登录页面
driver.get('https://kyfw.12306.cn/otn/login/init')
time.sleep(5)
# 对加载的页面进行截图并保存
driver.save_screenshot('code.png')
# 定位图片
code_img_element = driver.find_element_by_class_name('touclick-image')
lacation = code_img_element.location # 验证码图片左上角的坐标 lacation 它是个字典
size = code_img_element.size # 验证码图片对应的是长和宽 size 也是个字典
# 左上角和右下角坐标
rangle = (int(lacation['x']),int(lacation['y']),int(lacation['x']+size['width']),int(lacation['y']+size['height']))

i = Image.open('./code.png') # 打开整张截图
code_img_name = './yzm.png'
frame = i.crop(rangle) # crop() 根据指定区域进行裁剪
frame.save(code_img_name)

# 将验证码图片提交给超级鹰进行识别
chaojiying = Chaojiying_Client('Jerry1234 ', '123456', '914400')
im = open('yzm.png', 'rb').read()
print(chaojiying.PostPic(im, 9004)['pic_str'])


result = chaojiying.PostPic(im, 9004)['pic_str']
all_lst = [] # 存储要被点击的点的坐标 [[],[]]
if '|' in result: # 判断竖线是否在返回的结果中 如果有竖线就进行分割
    lst1 = result.split('|')
    count1 = len(lst1)  # 获取长度
    for i in range(count1):
        xy_lst = []
        x = int(lst1[i].split(',')[0])
        y = int(lst1[i].split(',')[1])
        xy_lst.append(x)
        xy_lst.append(y)
        all_lst.append(xy_lst)
else:
    x = int(result.split(',')[0])
    y = int(result.split(',')[1])
    xy_lst = []
    xy_lst.append(x)
    xy_lst.append(y)
    all_lst.append(xy_lst)
print(all_lst)

# 遍历列表使用行为链对每一个列表元素对应的x,y指定的位置进行点击
for l in all_lst:
    x = l[0]
    y = l[1]
    # 将参照物移动到验证码图片 code_img_element(验证码图片的元素)
    ActionChains(driver).move_to_element_with_offset(code_img_element,x,y).click().perform()
    time.sleep(0.5)

四、行为验证反爬

from selenium import  webdriver
import time
from selenium.webdriver import ActionChains
from selenium.common.exceptions import NoSuchElementException,StaleElementReferenceException

def login():
    driver = webdriver.Chrome()
    driver.get('https://i.qq.com/')
    time.sleep(2)
    # 切换iframe
    driver.switch_to.frame(driver.find_element_by_id('login_frame'))
    # 切换登录方式
    driver.find_element_by_id('switcher_plogin').click()
    driver.find_element_by_id('u').send_keys('192149641')
    driver.find_element_by_id('p').send_keys('logic12345')
    time.sleep(1)
    driver.find_element_by_id('login_button').click()
    time.sleep(2)
    # 创建行为链对象
    actions = ActionChains(driver)

    # 切换拖动验证的iframe tcaptcha_iframe
    driver.switch_to.frame(driver.find_element_by_id('tcaptcha_iframe'))
    # x坐标的偏移量
    x = 165
    flag = True
    while flag:
        try:
            # 定位拖动按钮
            tcaptcha_drag_thumb = driver.find_element_by_id('tcaptcha_drag_thumb')
            # 按下拖动
            actions.drag_and_drop_by_offset(tcaptcha_drag_thumb,xoffset=x,yoffset=0).perform()
        except NoSuchElementException:
            driver.quit()
            login()
        time.sleep(2)

        try:
            actions.drag_and_drop_by_offset(tcaptcha_drag_thumb, xoffset=x, yoffset=0).perform()
        except StaleElementReferenceException:
            pass
        x = x + 5 # 每次偏移量+5
        time.sleep(1)
        try:
            driver.find_element_by_id('feed_tab_my')
            break
        except NoSuchElementException:
            print('未登录到主页')

login()

参考文章
https://www.cnblogs.com/xiao-apple36/p/8878960.html

五、ip反爬

设置代理ip
http://httpbin.org/ip 返回当前的ip地址
https://www.ipip.net/ 查看当前的ip地址
https://h.wandouip.com/member/index 比较好用的ip代理平台

ua反爬

爬虫中非常重要的一种反反爬策略
user-agent 用户代理
解决方式
• 添加随机的user-agent
• fake_useragent

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值