【自动化系列】plawright过某音登录验证

admin 2024年4月19日23:40:54评论1 views字数 4297阅读14分19秒阅读模式

免责声明

【自动化系列】plawright过某音登录验证

文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业和非法用途,否则由此产生的一切后果与作者无关。若有侵权,请在公众号【爬虫逆向小林哥】联系作者

【自动化系列】plawright过某音登录验证

01

逆向目标

最近圈友高质量的文章一篇接一篇,倍感焦虑,告别内卷,拥抱金角

aHR0cHM6Ly9kb3VqaWEuZG91eWluLmNvbS9sb2dpbg==

02

抓包分析

某音投放平台的登录验证

【自动化系列】plawright过某音登录验证

03

逆向过程

过程没啥说的,难点就是底图还原跟locator定位(好久没写过selector了),真好啊 不用动脑子

通过率测了下是100%,过程不写了,直接放源码,需要的自提

【自动化系列】plawright过某音登录验证

记得改下面的地方

【自动化系列】plawright过某音登录验证

04

算法还原

import httpximport randomimport asyncioimport ddddocrfrom PIL import Imagefrom io import BytesIOfrom loguru import loggerfrom playwright.async_api import Page, Response, async_playwrightclass AwemeBrowser:    def __init__(self, session: str, headless: bool = False):        self.x = 0        self.y = ""        self.url1 = ""        self.url2 = ""        self.tag = False        self._session = session        self._headless = headless        self.ocr = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)    async def login(self, page: Page, username) -> None:        page.on("response", self.on_response)        await page.goto('aHR0cHM6Ly9kb3VqaWEuZG91eWluLmNvbS9sb2dpbg==')        await page.wait_for_timeout(self.wait_random)        if "扫码登录" not in await page.content():            logger.info("账号={}, 正常在线".format(username))        else:            await page.click('li:has-text("验证码登录")')            # 清空输入框            await page.evaluate('document.querySelector(".web-login-normal-input__input").value=""')            await page.evaluate('document.querySelector(".web-login-button-input__input").value=""')            # 账号密码登录            await page.wait_for_timeout(self.wait_random)            await page.type(selector=".web-login-normal-input__input", text=username, delay=100)            # await page.type(selector=".web-login-button-input__input", text=password, delay=100)            await page.wait_for_timeout(self.wait_random)            await page.click('span:has-text("获取验证码")')            await page.wait_for_timeout(self.wait_random)            num = 1            while True:                logger.warning("当前滑动次数: {}".format(num))                distance = await self.get_distance()                tracks = self.get_tracks(distance)                new_frame = page.frame_locator('#captcha_container > iframe')                slide = new_frame.locator('.captcha-slider-btn')                box = await slide.bounding_box()                await page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)                await page.mouse.down()                x = box["x"] + box["width"] / 2                for track in tracks:                    x += track                    await page.mouse.move(x, box["y"])                    await asyncio.sleep(random.uniform(0.005, 0.02))                await page.mouse.up()                await page.wait_for_timeout(self.wait_random)                num = num + 1                if num > 5 or self.tag:                    break                await page.wait_for_timeout(self.wait_random)    @property    def wait_random(self):        return random.randint(1000, 3000)    async def on_response(self, response: Response):        if "https://verify.zijieapi.com/captcha/get" in response.url:            result = await response.json()            data = result.get("data")            picture = data.get("question")            self.y = picture.get("tip_y")            self.url1 = picture.get("url1")            self.url2 = picture.get("url2")        if "https://verify.zijieapi.com/captcha/verify" in response.url:            result = await response.json()            if result.get("code") == 200:                logger.success("滑块通过, res={}".format(result))                self.tag = True    async def get_distance(self):        async with httpx.AsyncClient() as session:            response_1 = await session.get(self.url1)            response_2 = await session.get(self.url2)        image = Image.open(BytesIO(response_1.content))        width, height = image.size        sub_images = []        for i in range(6):            left = (i * width) // 6            right = ((i + 1) * width) // 6            sub_image = image.crop((left, 0, right, height))            sub_images.append(sub_image)        order = [1, 5, 4, 2, 0, 3]        new_images = [None] * 6        for i in range(6):            new_images[order[i]] = sub_images[i]        merged_image = Image.new('RGB', (width, height))        for i in range(6):            left = (i * width) // 6            right = ((i + 1) * width) // 6            merged_image.paste(new_images[i], (left, 0))        # 保存图片        merged_image.save('logs/images/captcha_restored.png')        img_byte = BytesIO()        merged_image.save(img_byte, format='JPEG')        url1_content = img_byte.getvalue()        ocr_response = self.ocr.slide_match(response_2.content, url1_content)        x = ocr_response['target'][0]        logger.info(f"滑动的距离为: {x}, 高度为: {self.y}")        return int(int(x) / 550 * 340) - 5    def get_tracks(self, distance):        track = []        current = 0        mid = distance * 4 / 5        t = 0.2        v = 1        while current < distance:            if current < mid:                a = 4            else:                a = -3            v0 = v            v = v0 + a * t            move = v0 * t + 1 / 2 * a * t * t            current += move            track.append(round(move))        return track    async def start(self, username):        async with async_playwright() as pwt:            browser = await pwt.chromium.launch_persistent_context(                headless=self._headless,                user_data_dir=self._session,                args=["--start-maximized", '--disable-blink-features=AutomationControlled'],                no_viewport=True  # 窗口最大化            )            await browser.add_init_script(path="logs/js/stealth.min.js")            page = await browser.new_page()            await self.login(page=page, username=username)async def main(username):    b = AwemeBrowser(session=f"logs/session/{username}")    await b.start(username)asyncio.run(main("18888888281"))

05

归纳总结

【自动化系列】plawright过某音登录验证

【自动化系列】plawright过某音登录验证

添加好友回复:交流群

原文始发于微信公众号(爬虫逆向小林哥):【自动化系列】plawright过某音登录验证

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月19日23:40:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【自动化系列】plawright过某音登录验证https://cn-sec.com/archives/2638392.html

发表评论

匿名网友 填写信息