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 Web框架Flask信号机制(signals)介绍
Jan 01 Python
浅谈Python 的枚举 Enum
Jun 12 Python
python PyTorch预训练示例
Feb 11 Python
Python实现的调用C语言函数功能简单实例
Mar 13 Python
python抖音表白程序源代码
Apr 07 Python
numpy linalg模块的具体使用方法
May 26 Python
python安装scipy的方法步骤
Jun 26 Python
flask 实现token机制的示例代码
Nov 07 Python
django 实现简单的插入视频
Apr 07 Python
python 日志模块 日志等级设置失效的解决方案
May 26 Python
关于多种方式完美解决Python pip命令下载第三方库的问题
Dec 21 Python
python drf各类组件的用法和作用
Jan 12 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
PHP写MySQL数据 实现代码
2009/06/15 PHP
PHP编程快速实现数组去重的方法详解
2017/07/22 PHP
原生JS实现Ajax通过POST方式与PHP进行交互的方法示例
2018/05/12 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
php7 list()、session及其他模块的修改实例分析
2020/05/25 PHP
表单的一些基本用法与技巧
2006/07/15 Javascript
JavaScript对象、属性、事件手册集合方便查询
2010/07/04 Javascript
基于JQuery制作可编辑的表格特效
2014/12/23 Javascript
javascript判断元素存在和判断元素存在于实时的dom中的方法
2017/01/17 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
node koa2实现上传图片并且同步上传到七牛云存储
2017/07/31 Javascript
Webpack实战加载SVG的方法
2017/12/26 Javascript
bootstrap table实现横向合并与纵向合并
2019/07/18 Javascript
jQuery/JS监听input输入框值变化实例
2019/10/17 jQuery
js实现数字滚动特效
2019/12/16 Javascript
小程序Scroll-view上拉滚动刷新数据
2020/06/21 Javascript
[58:23]LGD vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python中的localtime()方法使用详解
2015/05/22 Python
python dict 字典 以及 赋值 引用的一些实例(详解)
2017/01/20 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
2017/11/30 Python
使用requests库制作Python爬虫
2018/03/25 Python
python-tornado的接口用swagger进行包装的实例
2019/08/29 Python
html5桌面通知(Web Notifications)实例解析
2014/07/07 HTML / CSS
canvas如何实现多张图片编辑的图片编辑器
2020/03/10 HTML / CSS
Easy Spirit官网:美国休闲鞋履中的代表品牌
2019/04/12 全球购物
应聘护士自荐信
2013/10/21 职场文书
采购员岗位职责
2013/11/15 职场文书
环境科学专业优秀毕业生自荐书
2014/02/03 职场文书
小学生作文评语
2014/04/18 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
向国旗敬礼学生寄语大全
2014/09/30 职场文书
加强机关作风建设心得体会
2014/10/22 职场文书
党支部四风整改方案
2014/10/25 职场文书
工作检讨书怎么写
2015/01/23 职场文书
2015年世界环境日活动总结
2015/02/11 职场文书
描述鲁迅的名言整理,一生受用
2019/08/08 职场文书