drissionpage知识整理与某数等反爬产品绕过实战

DrissionPage知识整理与反爬实战

概述

DrissionPage是一个基于 Python 的网页自动化工具。既能控制浏览器,也能收发数据包,还能把两者合而为一。可兼顾浏览器自动化的便利性和 requests 的高效率。功能强大,语法简洁优雅,代码量少,对新手友好。

入门文档

drissionpage作者提供了详细的入门教程,这里就列出用法了,需要时直接到官方文档查询即可。

官方文档还提供了几个大佬录制的视频教程,方便食用
在这里插入图片描述

主页面对象

主页面对象有 3 种,它们通常是程序的入口:

  • ChromiumPage:单纯用于操作浏览器的页面对象
  • WebPage:整合浏览器控制和收发数据包于一体的页面对象
  • SessionPage:单纯用于收发数据包的页面对象

我的理解是:
WebPage其实整合了ChromiumPage和SessionPage两个页面对象
在这里插入图片描述

而ChromiumPage跟selenium、playwright应用上差不多,可操控浏览器
SessionPage是一个使用使用Session(requests 库)对象的页面,是一个使用使用Session(requests 库)对象的页面,它使用 POM 模式封装了网络连接和 html 解析功能,收发数据包效果跟requests相同,不过它提供了丰富的功能。

采集案例

某书搜索列表页

刚遇到问题,就是某书的搜索列表页是没有滚动条的,一般情况下只能鼠标滚轮滚动
大家估计都会使用下面这种方式来实现翻页

wp = WebPage()
wp.get('url')
wp.listen.start('web/v1/search/notes')
ac = Actions(wp)
packet = wp.listen.wait()
ac.scroll(delta_y=1500)

但是这种方式循环滚动两次后,会发现一直卡在第三次循环,这是啥原因呢

这是因为此时的scroll是对driver对象进行操作的,那它只会滚动到浏览器界面的最大值,不会再重置后继续滚动了,也就导致了程序一直处于wp.listen.wait()这一步。

这时其实可以使用执行JavaScript代码的方式实现屏幕滚动,下面代码既可以解决问题

wp.run_js('''
// 滚动函数
function scrollDown() {
  window.scrollBy(0, 2000); // 向下滚动2000像素
}
 
// 设置定时器,每隔1秒调用一次滚动函数
setInterval(scrollDown, 1000);
''')

说到底scroll方法操作的对象是元素。

某瓣小说封面

简单采集某瓣小说封面,更多案例可以看官方文档提供的。

import os.path

from DrissionPage import ChromiumPage, ChromiumOptions
from DrissionPage import SessionPage


def download():
    dp = ChromiumOptions().set_paths(browser_path=r'C:\Program Files\Google\Chrome\Application\chrome.exe')
    page = ChromiumPage(dp)

    page.get('https://book.douban.com/tag/小说?start=0&type=T', retry=3, interval=2, timeout=15)

    for _ in range(2):
        for book in page.eles('x://li[@class="subject-item"]'):
            book_name = book.ele('x://h2/a').attr('title')
            img = book('x://img')
            img.save(path='./img/', name=f"{book_name}.png")
            print(f"{book_name}.png 保存成功!")

        # 点击下一页
        page('后页>').click()
        page.wait.load_start()

    page.close()


def headless_download():
    """ 无头模拟实现 """
    page = SessionPage()

    if not os.path.exists('./img'):
        os.mkdir('./img')

    for _ in range(2):
        page.get('https://book.douban.com/tag/小说?start={}&type=T'.format(_ * 20), retry=3, interval=2, timeout=15)
        for book in page.eles('x://li[@class="subject-item"]'):
            book_name = book.ele('x://h2/a').attr('title')
            img = book('x://img')
            img_url = img.attr('src')
            page.download.add(img_url, save_path='./img', rename=book_name + '.jpg')
            print(f"{book_name}.png 保存成功!")

    page.close()


if __name__ == '__main__':
    headless_download()

反爬产品绕过实战

工作中比较需要完整的案例,如果是单一应用点则直接从官方教程查询即可,下面这些案例都在正常和无头浏览器下测试成功。

某数六代

目标网址

专利局公告网

破解源码

这里很奇怪,就是如果不设置set_user_agent的话,无头环境下根本拿不到cookie,请求直接400

import requests
from DrissionPage import ChromiumOptions, WebPage

base_url = 'base_url'
headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Referer": 'base_url',
    "Upgrade-Insecure-Requests": "1",
    "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",
}


def gen_rs_cookie():
    dp = ChromiumOptions()
    # dp.no_imgs(True).mute(True)
    # dp.incognito()  # 匿名模式
    dp.headless()  # 无头模式
    # dp.set_argument('--no-sandbox')  # 无沙盒模式
    # dp.set_argument('--disable-gpu')  # 禁用gpu加速
    dp.set_argument('--start-maximized')  # 设置启动时最大化
    # dp.set_argument('--disable-blink-features=AutomationControlled')
    dp.set_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')
    page = WebPage(mode='d', chromium_options=dp)
    page.get(base_url)
    try:
        cookies = page.cookies().as_dict()
        print(cookies)
    finally:
        page.quit()
    return cookies


def query():
    cookies = gen_rs_cookie()
    resp = requests.get(base_url, cookies=cookies, headers=headers)
    print('破解结果: {}'.format('成功' if resp.status_code == 200 else '失败'))


if __name__ == '__main__':
    query()

Akamai

目标网址

DHL物流

破解源码

from DrissionPage import ChromiumOptions, WebPage

base_url = 'base_url '


def crack_5sd():
    dp = ChromiumOptions()
    dp.headless()  # 无头模式
    dp.set_argument('--no-sandbox')  # 无沙盒模式
    dp.set_argument('--disable-gpu')  # 禁用gpu加速
    dp.set_argument('--start-maximized')  # 设置启动时最大化
    page = WebPage(mode='d', chromium_options=dp)
    page.get(base_url)
    page.wait(1)
    try:
        cookie = page.cookies().as_dict()
        print(cookie.get('_abck'))
    finally:
        page.quit()


if __name__ == '__main__':
    crack_5sd()

5秒盾

目标网址

rucaptcha

破解源码

这个也是,如果不设置set_user_agent的话,无头环境下无法成功验证。

from DrissionPage import ChromiumOptions, WebPage

base_url = 'base_url'


def crack_5sd():
    dp = ChromiumOptions()
    # dp.incognito()  # 匿名模式,开启过不了
    dp.headless()  # 无头模式
    # dp.set_argument('--no-sandbox')  # 无沙盒模式
    # dp.set_argument('--disable-gpu')  # 禁用gpu加速
    dp.set_argument('--start-maximized')  # 设置启动时最大化
    dp.set_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')
    page = WebPage(mode='d', chromium_options=dp)
    page.get(base_url)

    try:
        # 验证可能需要一段时间
        while True:
            if '正在验证您是否是真人' in page.html:
                page.wait(2)
            else:
                break
        try:
            div = page.ele('x:div.container').html
        except Exception as e:
            print(e)
            div = page.html
        print(div)
        print('破解结果: {}'.format('失败' if '请稍候…' in div else '成功'))
    finally:
        page.quit()


if __name__ == '__main__':
    crack_5sd()

某里滑块

目标网址

某车网

破解源码

这个怪得很,dp.headless()过不了无头,只能用这个dp.set_argument('--headless')

from DrissionPage import ChromiumOptions, WebPage

base_url = 'base_url'


def crack_alhk():
    dp = ChromiumOptions()
    # dp.headless()  # 无头模式  过不了
    dp.set_argument('--headless')  # 无头模式 new
    dp.set_argument('--no-sandbox')  # 无沙盒模式
    dp.set_argument('--disable-gpu')  # 禁用gpu加速
    dp.set_argument('--start-maximized')  # 设置启动时最大化
    dp.set_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')
    page = WebPage(mode='d', chromium_options=dp)
    page.get(base_url)
    if '欢迎来到e车网' in page.html:
        return

    try:
        button = page.ele('@id=aliyunCaptcha-sliding-slider')
        page.actions.move_to(button).hold()
        page.actions.move(offset_x=320, offset_y=0, duration=0.5)
        page.actions.release()
        page.wait(2)
        print('破解结果: {}'.format('成功' if '欢迎来到e车网' in page.html else '失败'))
    finally:
        page.quit()


if __name__ == '__main__':
    crack_alhk()

点选验证码

目标网址

某省政府采购网

破解源码

复刻十一姐教程案例的hhh

import os.path
import time

import cv2
from DrissionPage import ChromiumOptions, WebPage


def click_img():
    yzm_xy = []

    def mouse_callback(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
            print(f'鼠标点击处的像素坐标:({x}, {y})')
            yzm_xy.append({'x': x, 'y': y})

    # 点击图片并获得坐标
    img = cv2.imread('captcha.jpg')
    cv2.namedWindow('Image')
    cv2.setMouseCallback('Image', mouse_callback)
    cv2.imshow('Image', img)
    while True:
        cv2.imshow('Image', img)
        if cv2.waitKey(1) == 13:
            break
    cv2.destroyAllWindows()

    return yzm_xy


def crack_dx():
    dp = ChromiumOptions()
    # dp.no_imgs(True).mute(True)
    # dp.incognito()  # 匿名模式
    # dp.headless()  # 无头模式
    # dp.set_argument('--no-sandbox')  # 无沙盒模式
    # dp.set_argument('--disable-gpu')  # 禁用gpu加速
    dp.set_argument('--start-maximized')  # 设置启动时最大化
    # dp.set_argument('--disable-blink-features=AutomationControlled')
    # dp.set_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')
    page = WebPage(mode='d', chromium_options=dp)
    page.get('base_url')
    page.refresh()  # 重新加载页面
    page.wait(1)

    try:
        page.ele('text=>').click()  # 点击下一页
        page.wait(2)
        # 保存验证码图片
        print('要点击的文字: ', page.ele('@class=verify-msg').text)
        img_obj = page.ele('x://div[@class="verify-img-panel"]/img')
        if os.path.exists('./captcha.jpg'):
            os.remove('./captcha.jpg')
        img_obj.save('./', name='captcha.jpg')

        # 获取文字验证码点击位置
        yzm_xy = click_img()

        # 根据点击位置实现鼠标点击
        for xy in yzm_xy:
            page.actions.move_to(img_obj, offset_x=int(xy['x'] / 310 * 350), offset_y=int(xy['y'] / 155 * 175),
                                 duration=0.1).click()
            time.sleep(1)

        # 打印列表页数据
        for tr in page.eles('x://tr')[1:11]:
            tds = [td.text.strip() for td in tr.eles('x:td')]
            print(tds)

    finally:
        page.quit()


if __name__ == '__main__':
    crack_dx()

写在最后

over~

### 绕过 DrissionPage 加密的方式并不可取 尝试绕过任何合法软件的安全措施不仅违道德规范和服务条款,还可能触犯法律。对于DrissionPage这样的工具而言,其设计初衷是为了保护用户数据安全以及防止滥用。 如果遇到因为加密机制而导致的功能障碍或兼容性问题,建议通过官方渠道馈获取帮助和支持。同时,在开发过程中应当遵循正当途径解决问题: - **理解现有API接口**:深入研究文档了解已公开可调用的方法[^1]。 - **利用开源社区资源**:许多开发者会在GitHub等平台上分享经验解决方案[^4]。 - **寻求专业咨询服务**:当内部技术团队无法解决时,联系第三方专家或许能提供更高效的办法。 ### 替代方案探讨 针对特定应用场景下的需求,可以选择其他合适的技术栈来满足业务逻辑而不必依赖于破解既有系统: #### 使用对称加密算法构建自有框架 根据项目特点挑选合适的对称加密标准如AES,并采用C语言编写核心模块编译成动态链接库文件(SO),以此增强移动端应用安全性的同时降低被逆向工程的风险。 ```c #include <openssl/aes.h> // ...省略部分代码... void encrypt(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, const unsigned char *iv, unsigned char ciphertext[]) { AES_KEY aesKey; AES_set_encrypt_key(key, 256, &aesKey); AES_cbc_encrypt(plaintext, ciphertext, plaintext_len, &aesKey, iv, AES_ENCRYPT); } ``` #### 应用自适应单向散列函数提升密码存储强度 为了更好地抵御暴力破解攻击,推荐选用bcrypt、PBKDF2、scrypt 或 argon2 这样的现代哈希算法作为 PasswordEncoder 的底层实现[^2]。 ```python import bcrypt password = b"super secret password" salt = bcrypt.gensalt() hashed_password = bcrypt.hashpw(password, salt) if bcrypt.checkpw(password, hashed_password): print("It Matches!") else: print("Does not match") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九月镇灵将

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值