Python中常见的反爬机制及其破解方法总结


Posted in Python onJune 10, 2021

一、常见反爬机制及其破解方式

封禁IP,使用cookie等前面文章已经讲过

现在主要将下面的:

​ ~ 验证码
​ —> 文字验证码 —> OCR(光学文字识别)—> 接口 / easyocr
​ 程序自己解决不了的问题就可以考虑使用三方接口(付费/免费)
​ —> 行为验证码 —> 超级鹰
​ ~ 手机号+短信验证码
​ —> 接码平台
​ ~ 动态内容
​ —> JavaScript逆向 —> 找到提供数据的API接口
​ —> 手机抓接口 —> 抓包工具(Charles / Fiddler)
​ —> Selenium直接模拟浏览器操作获取动态内容
​ ~ find_element_by_xxx / find_elements_by_xxx
​ ~ page_source —> 获取包含动态内容的网页源代码
​ —> JavaScript加密和混淆技术 —> 读懂JavaScript是反反爬的前提
​ ~ 字体反爬 / 内容来自于抠图
​ —> 例子

bytes —> 不变字节串 —> 二进制 —> BytesIO
str —> 不变字符串 —> 可阅读的字符 —> StringIO

二、调用三方API接口数据(天行数据)

import requests

for page in range(1, 6):
    response = requests.get(
        'http://api.tianapi.com/topnews/index',
        params={
            'key': 'd5eace66dccd771e36767ce3563efa09',
            'page': page,
            'num': 20,
            'word': '华为',
            'src': '人民日报'
        }
    )
    result = response.json()
    for news in result['newslist']:
        print(news['title'])
        print(news['url'])

三、OCR(光学文字识别)库

python 自带的easyocr库

import easyocr
reader = easyocr.Reader(['ch_sim', 'en'], gpu=False)
print(reader.readtext('./files/captcha.jpg', detail=0))

例子:阿里云邮箱自动登陆

import io

import easyocr

from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

browser = webdriver.Chrome()
browser.set_window_size(1280, 960)
browser.get('http://mail.1000phone.com/')
# 隐式等待(下面的方法在工作时如果取不到就等10秒)
browser.implicitly_wait(10)
# 显式等待
wait = WebDriverWait(browser, 10)
wait.until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '.login_panel_iframe')))
iframe1 = browser.find_element_by_css_selector('.login_panel_iframe')
# 记录iframe1的位置(相对位置)
x1, y1 = iframe1.location['x'], iframe1.location['y']
# Chrome对象的switch_to属性的frame方法,可以从页面切换到iframe中
browser.switch_to.frame(iframe1)
iframe2 = browser.find_element_by_css_selector('#ding-login-iframe')
x2, y2 = iframe2.location['x'], iframe2.location['y']
browser.switch_to.frame(iframe2)
username_input = browser.find_element_by_css_selector('#username')
# 模拟用户输入
username_input.send_keys('xx@1000phone.com')
password_input = browser.find_element_by_css_selector('#password')
password_input.send_keys('xxxxx!!')
# 创建一个等待对象
wait = WebDriverWait(browser, 10)
wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '#login_checkcode_ico')))
captcha_img = browser.find_element_by_css_selector('#login_checkcode_ico')
# WebElement对象的size属性代表元素宽度和高度,location属性代表元素在窗口中的位置
size, location = captcha_img.size, captcha_img.location
x3, y3, width, height = location['x'], location['y'], size['width'], size['height']
# 截取整个浏览器窗口的图片获得图片的二进制数据
image_data = browser.get_screenshot_as_png()
# bytes(只读字节串) ----> io.BytesIO(可写字节串)---> getvalue() ---> bytes
# str(只读字符串) ----> io.StringIO(可写字符串)---> getvalue() ---> str
browser_image = Image.open(io.BytesIO(image_data))
# 从截图上剪裁出验证码的图片
x, y = x1 + x2 + x3, y1 + y2 + y3
# Windows系统的写法 ---> 如果截图有问题就把坐标写死
# print(x, y, width, height)
checkcode_image = browser_image.crop((x * 1.25, y * 1.25, (x + width) * 1.25, (y + height) * 1.25))
# macOS系统的写法
# checkcode_image = browser_image.crop((x * 2, y * 2, (x + width) * 2, (y + height) * 2))
checkcode_image.save('result.png')
# 通过easyocr做光学文字识别
reader = easyocr.Reader(['en'], gpu=False)
code = reader.readtext('result.png', detail=0)[0]
# 将识别出的验证码输入文本框
checkcode_input = browser.find_element_by_css_selector('#login_checkcode')
checkcode_input.send_keys(code)
login_button = browser.find_element_by_css_selector('#login_submit_btn')
# 模拟用户点击
login_button.click()

四、第三方打码平台(超级鹰打码平台)

补充:需要使用python 自带pillow库

"""
Pillow库 ---> PIL ---> Python Image Library
"""
from PIL import Image, ImageFilter

# 加载图像
guido_image = Image.open('guido.jpg')
# 剪裁
guido_image.crop((80, 40, 310, 350)).show()
# 滤镜
guido_image.filter(ImageFilter.CONTOUR).show()
# 缩略图
guido_image.thumbnail((125, 185))
# 显示图像
guido_image.show()

编写超级鹰打码平台类

from hashlib import md5

import requests


class ChaojiyingClient:

    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 post_pic(self, image_data, code_type):
        """
        image_data: 图片字节
        code_type: 验证码类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': code_type,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', image_data)}
        response = requests.post(
            url='http://upload.chaojiying.net/Upload/Processing.php',
            data=params,
            files=files,
            headers=self.headers
        )
        return response.json()

    # 超级鹰错误反馈函数(仅用于给超级鹰平台反馈)
    def report_error(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()


if __name__ == '__main__':
    chaojiying = ChaojiyingClient('账户', '密码x', 'ID')  # 用户中心>>软件ID 生成一个替换 96001
    with open('img.png', 'rb') as file:
        image_data = file.read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
        print(chaojiying.post_pic(image_data, 1902))  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()

例子:使用超级鹰进行阿里云邮箱自动登陆

import io

import easyocr

from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

from chaojiying import ChaojiyingClient

browser = webdriver.Chrome()
browser.set_window_size(1280, 960)
browser.get('http://mail.1000phone.com/')
# 隐式等待(下面的方法在工作时如果取不到就等10秒)
browser.implicitly_wait(10)
# 显式等待
wait = WebDriverWait(browser, 10)
wait.until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '.login_panel_iframe')))
iframe1 = browser.find_element_by_css_selector('.login_panel_iframe')
# 记录iframe1的位置(相对位置)
x1, y1 = iframe1.location['x'], iframe1.location['y']
# Chrome对象的switch_to属性的frame方法,可以从页面切换到iframe中
browser.switch_to.frame(iframe1)
iframe2 = browser.find_element_by_css_selector('#ding-login-iframe')
x2, y2 = iframe2.location['x'], iframe2.location['y']
browser.switch_to.frame(iframe2)
username_input = browser.find_element_by_css_selector('#username')
# 模拟用户输入
username_input.send_keys('xxxx.com')
password_input = browser.find_element_by_css_selector('#password')
password_input.send_keys('xxxx!!')
# 创建一个等待对象
wait = WebDriverWait(browser, 10)
wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '#login_checkcode_ico')))
captcha_img = browser.find_element_by_css_selector('#login_checkcode_ico')
# WebElement对象的size属性代表元素宽度和高度,location属性代表元素在窗口中的位置
size, location = captcha_img.size, captcha_img.location
x3, y3, width, height = location['x'], location['y'], size['width'], size['height']
# 截取整个浏览器窗口的图片获得图片的二进制数据
image_data = browser.get_screenshot_as_png()
# bytes(只读字节串) ----> io.BytesIO(可写字节串)---> getvalue() ---> bytes
# str(只读字符串) ----> io.StringIO(可写字符串)---> getvalue() ---> str
browser_image = Image.open(io.BytesIO(image_data))
# 从截图上剪裁出验证码的图片
x, y = x1 + x2 + x3, y1 + y2 + y3
# Windows系统的写法 ---> 如果截图有问题就把坐标写死
# print(x, y, width, height)
checkcode_image = browser_image.crop((x * 1.25, y * 1.25, (x + width) * 1.25, (y + height) * 1.25))
# macOS系统的写法
# checkcode_image = browser_image.crop((x * 2, y * 2, (x + width) * 2, (y + height) * 2))
checkcode_image.save('result.png')
# 通过超级鹰打码平台打码
chaojiying = ChaojiyingClient('账户', '密码', 'ID')
with open('result.png', 'rb') as file:
    image_data = file.read()
    result_dict = chaojiying.post_pic(image_data, 1902)
# 将识别出的验证码输入文本框
checkcode_input = browser.find_element_by_css_selector('#login_checkcode')
checkcode_input.send_keys(result_dict['pic_str'])
login_button = browser.find_element_by_css_selector('#login_submit_btn')
# 模拟用户点击
login_button.click()

五、通过接码平台接收手机验证码(隐私短信平台)

通过隐私短信平台接收验证码(免费)

import re

import bs4
import requests

pattern = re.compile(r'\d{4,6}')

resp = requests.get('https://www.yinsiduanxin.com/china-phone-number/verification-code-16521686439.html')
soup = bs4.BeautifulSoup(resp.text, 'html.parser')
# print(resp.text)
td = soup.select_one('body > div.container > div:nth-child(4) > div:nth-child(3) > div.main > div.layui-row > table > tbody > tr:nth-child(1) > td:nth-child(2)')
results = pattern.findall(td.text)
print(results[0])

到此这篇关于Python中常见的反爬机制及其破解方法总结的文章就介绍到这了,更多相关Python反爬机制及其破解内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python去除列表中重复元素的方法
Mar 20 Python
python运行时间的几种方法
Jun 17 Python
20招让你的Python飞起来!
Sep 27 Python
python中urlparse模块介绍与使用示例
Nov 19 Python
Python登录并获取CSDN博客所有文章列表代码实例
Dec 28 Python
python去除扩展名的实例讲解
Apr 23 Python
python 多线程将大文件分开下载后在合并的实例
Nov 09 Python
python中partial()基础用法说明
Dec 30 Python
在Python中通过getattr获取对象引用的方法
Jan 21 Python
python设置随机种子实例讲解
Sep 12 Python
Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)
Jul 20 Python
Python调用REST API接口的几种方式汇总
Oct 19 Python
Pytorch可视化的几种实现方法
OpenCV-Python实现怀旧滤镜与连环画滤镜
OpenCV-Python实现轮廓的特征值
Jun 09 #Python
再也不用花钱买漫画!Python爬取某漫画的脚本及源码
Jun 09 #Python
Python的这些库,你知道多少?
OpenCV-Python使用cv2实现傅里叶变换
Python合并多张图片成PDF
Jun 09 #Python
You might like
LotusPhp笔记之:基于ObjectUtil组件的使用分析
2013/05/06 PHP
php中获取主机名、协议及IP地址的方法
2014/11/18 PHP
Ajax,UTF-8还是GB2312 eval 还是execScript
2008/11/13 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
jquery动态增加text元素以及删除文本内容实例代码
2013/07/01 Javascript
avalonjs实现仿微博的图片拖动特效
2015/05/06 Javascript
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
2015/08/21 NodeJs
JAVA Web实时消息后台服务器推送技术---GoEasy
2016/11/04 Javascript
Angular2学习教程之组件中的DOM操作详解
2017/05/28 Javascript
vue单页应用加百度统计代码(亲测有效)
2018/01/31 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
解决Vue+Element ui开发中碰到的IE问题
2018/09/03 Javascript
vue click.stop阻止点击事件继续传播的方法
2018/09/04 Javascript
Jquery异步上传文件代码实例
2019/11/13 jQuery
vue实现简单瀑布流布局
2020/05/28 Javascript
javascript执行上下文、变量对象实例分析
2020/04/25 Javascript
javascript实现简单留言板案例
2021/02/09 Javascript
在Python中使用poplib模块收取邮件的教程
2015/04/29 Python
详解Python各大聊天系统的屏蔽脏话功能原理
2016/12/01 Python
利用python程序帮大家清理windows垃圾
2017/01/15 Python
分析Python中解析构建数据知识
2018/01/20 Python
Python进阶:生成器 懒人版本的迭代器详解
2019/06/29 Python
Django框架视图层URL映射与反向解析实例分析
2019/07/29 Python
Python中对象的比较操作==和is区别详析
2021/02/12 Python
HTML5之语义标签介绍
2016/07/07 HTML / CSS
W Concept美国:精选全球独立设计师
2017/02/22 全球购物
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
Oracle中delete,truncate和drop的区别
2016/05/05 面试题
英文版餐饮业求职信
2013/10/18 职场文书
质检的岗位职责
2013/11/17 职场文书
工会趣味活动方案
2014/08/18 职场文书
2014年销售部工作总结
2014/12/01 职场文书
西岭雪山导游词
2015/02/06 职场文书
教师节寄语2015
2015/03/23 职场文书
Java获取e.printStackTrace()打印的信息方式
2021/08/07 Java/Android
Echarts如何重新渲染实例详解
2022/05/30 Javascript