`

爬虫—phantomJS极验拼图破解

阅读更多

  在全国企业信用信息系统中搜索信息时,可以看到以下验证码:



 

  破解思路:

    1.从div中或取乱序的图片及坐标,乱序图片如下图:

     

 

     2.根据获取到的乱序图片及坐标将图片拼完整,如下图:

      

 ,

 

     3.计算两张图片的像素差,并计算缺口位置,如下图:

      

 

     4.根据缺口位置模拟人的行为拖动滑块

  具体代码如下:

  

def get_merge_image(filename,location_list):
    '''
    根据位置对图片进行合并还原
    :filename:图片
    :location_list:图片位置
    '''
    pass
    im = image.open(filename)
    new_im = image.new('RGB', (260,116))
    im_list_upper=[]
    im_list_down=[]
    for location in location_list:
        if location['y']==-58:
            pass
            im_list_upper.append(im.crop((abs(location['x']),58,abs(location['x'])+10,166)))
        if location['y']==0:
            pass
            im_list_down.append(im.crop((abs(location['x']),0,abs(location['x'])+10,58)))
    new_im = image.new('RGB', (260,116))
    x_offset = 0
    for im in im_list_upper:
        new_im.paste(im, (x_offset,0))
        x_offset += im.size[0]
    x_offset = 0
    for im in im_list_down:
        new_im.paste(im, (x_offset,58))
        x_offset += im.size[0]
    return new_im

def get_image(driver,div):
    '''
    下载并还原图片
    :driver:webdriver
    :div:图片的div
    '''
    pass
    #找到图片所在的div
    background_images=driver.find_elements_by_xpath(div)
    location_list=[]
    imageurl=''
    for background_image in background_images:
        location={}
        #在html里面解析出小图片的url地址,还有长高的数值
        location['x']=int(re.findall("background-image: url\((\S+)\); background-position: (.*)px (.*)px;",background_image.get_attribute('style'))[0][1])
        location['y']=int(re.findall("background-image: url\((\S+)\); background-position: (.*)px (.*)px;",background_image.get_attribute('style'))[0][2])
        imageurl=re.findall("background-image: url\((\S+)\); background-position: (.*)px (.*)px;",background_image.get_attribute('style'))[0][0]
        location_list.append(location)
    imageurl=imageurl.replace("webp","jpg")
    image_bytes = urllib.request.urlopen(imageurl).read()
    data_stream = BytesIO(image_bytes)
    jpgfile = Image.open(data_stream)
    jpgfile.save("%s.png" % 'rr')

    #重新合并图片
    image=get_merge_image("rr.png",location_list )
    return image

# 计算缺口位置
def getlocation(image3):
    for i in range(5,260):
        for j in range(0,116):
             pixel1 = image3.getpixel((i, j))
             if(pixel1[0]>100 or pixel1[1]>100):
                return i

# 获取图片并计算缺口位置
def getImgAndLoc(driver):
    #     下载图片
    image1 = get_image(driver, "//div[@class='gt_cut_bg gt_show']/div")
    image2 = get_image(driver, "//div[@class='gt_cut_fullbg gt_show']/div")
    image3 = ImageChops.difference(image1, image2)
    image1.save("%s.png" % '3')
    image2.save("%s.png" % '4')
    image3.save("%s.png" % '5')
    loc = getlocation(image3)
    print("缺口位置:", loc)
    return loc

# 移动滑块
def mourse(driver,element,loc):
    action = ActionChains(driver)
    action.move_to_element(to_element=element).perform()
    action.click_and_hold(element).perform()  # 鼠标左键按下不放
    action.reset_actions()
    id = random.randint(0, 2)
    print('track==%d'%id)
   #将图片划分成几个区域,对不同区域使用不同的行为数据,进一步提高通过率
    if loc <= 75:
        moveStep = gehostMouse.read_txt('./trackData/1_%d.txt' % id)
    elif loc > 75 and loc <= 100:
        moveStep = gehostMouse.read_txt('./trackData/2_%d.txt' % id)
    elif loc > 100 and loc <= 150:
        moveStep = gehostMouse.read_txt('./trackData/3_%d.txt' % id)
    elif loc > 150 and loc <= 200:
        moveStep = gehostMouse.read_txt('./trackData/4_%d.txt' % id)
    else:
        moveStep = gehostMouse.read_txt('./trackData/5_%d.txt' % id)
    countStep = 0
    idx = 0
    while countStep <= loc-5 and idx < len(moveStep):
        # print(moveStep[idx][0], moveStep[idx][1], moveStep[idx][2])
        action.move_by_offset(moveStep[idx][0], moveStep[idx][1]).perform()  # 移动一个位移
        action.reset_actions()
        time.sleep(moveStep[idx][2])  # 等待停顿时间
        countStep += moveStep[idx][0]
        idx += 1
    # countStep-=moveStep[idx-1][0]
    print(countStep)
    subStep = loc-5-countStep
    print("subStep=",subStep)
    while subStep <0:
        rd=random.randint(-2,-1)
        action.move_by_offset(rd, 0).perform()
        action.reset_actions()
        subStep-=rd
        time.sleep(random.randint(5, 10) / 100)
    action.release().perform()  # 鼠标左键松开
    action.reset_actions()

 说明:

   1.滑块滑动距离=缺口位置-5 的原因是滑块的位置相对于缺口位置的计算距离来说,滑块初始位置离图片最左边大约距离5个像素距离。

   2.验证码破解的难点是模拟人的行为数据,滑太快或太慢都不行,人的行为是一个慢-快-慢的过程,因此我通过获取自己滑动验证码的行为数据,生成了以下形式的几组数据:

   

 

      第一列是x方向的偏移量,第二列是y方向的偏移量,第三列为耗时。可以使用GhostMouse获取鼠标行为数据。

    GhostMouse获取鼠标偏移量数据代码如下:

   

import os
# xyd_typical = (1,0,0.04)
def read_rms(file_rms,file_txt):
    with open(file_rms) as fp:  # os.path.sep
        LMouse_down = False
        for line in fp:
            if 'LMouse down' in line or (LMouse_down == True and 'Move' in line):
                if 'LMouse down' in line:
                    LMouse_down = True
                    xyd_records = []
                    x_last, y_last = 0, 0  # 保证第一个偏移量为实际开始位置
                xy_pos = line.split('(')[1].split(')')[0].split(',')
                x_pos, y_pos = [int(i) for i in xy_pos]
                continue
            if LMouse_down == True and 'Delay' in line:
                x_delta, y_delta = x_pos - x_last, y_pos - y_last
                if x_delta == 0 and y_delta == 0 and len(xyd_records) != 0:  # len 可能起点就是0,0
                    continue
                else:
                    delay = float(line.split(' ')[1].split('}')[0])
                    xyd_records.append((x_delta, y_delta, delay))
                    x_last, y_last = x_pos, y_pos
                    continue

            # {LMouse up (790,659)}
            if LMouse_down == True and 'LMouse up' in line:
                # x_init y_init x_change y_change
                # x y d 每一次偏移量
                # x y d
                with open(file_txt, 'a') as fh_txt:
                    # x_change = sum(x for x,y,d in xyd_records)
                    x_init = xyd_records[0][0]
                    y_init = xyd_records[0][1]
                    x_change = sum(x for x, y, d in xyd_records[1:])
                    y_change = sum(y for x, y, d in xyd_records[1:])
                    fh_txt.write('{} {} {} {}\n'.format(x_init, y_init, x_change, y_change))  # 加os.linesep是'\r\n'
                    for x, y, d in xyd_records[1:]:  # 第一个记录为起始位置,value记录之后的每一次偏移
                        fh_txt.write('{} {} {}\n'.format(x, y, d))
                LMouse_down = False
                xyd_records = []

def read_txt(file_txt):
    with open(file_txt, 'r') as fp:
        result = []  # (x_init, y_init, x_change, y_chang): [(x0,y0,d0), (x1,y1,d1)...]
        # i=0;
        for line in fp:
            line = line.strip().split()
            if len(line) == 3:
                    x, y, d = line
                    x, y, d = int(x), int(y), float(d)
                    tp=(x,y,d)
                    result.append(tp)
    return result

def main():
    # file_rms = os.path.join(os.path.abspath('.'), 'night.rms')
    file_txt = os.path.join(os.path.abspath('.'), 'mouse.txt')
    # read_rms(file_rms,file_txt)
    result = read_txt(file_txt)
    for k, v in result.items():
        print(k,v)

if __name__ == '__main__':
    pass
    main()

    当然也可以通过request方式模拟请求破解验证码,但需要的参数需要通过其js文件才能搞明白,现在的js文件都加密了,目前能力解决不了。(可参考:http://www.jianshu.com/p/3726581d218a)

  • 大小: 32.4 KB
  • 大小: 30 KB
  • 大小: 12.4 KB
  • 大小: 36.2 KB
  • 大小: 50.6 KB
  • 大小: 11.1 KB
分享到:
评论

相关推荐

    linux 开源爬虫开发包phantomjs

    PhantomJS是一款基于Webkit内核的开源无头浏览器,专为自动化测试、网页截图、网络监测以及网页爬虫等任务而设计。在Linux环境中,它提供了在命令行上运行JavaScript的能力,使得开发者无需通过完整的GUI界面即可...

    Python 爬虫可用 phantomjs-2.1.1-windows.rar phantomjs 的windows 支持程序

    在Python爬虫领域,PhantomJS经常被用作模拟浏览器环境,执行JavaScript,获取动态加载内容,或者解决依赖用户交互才能展现的数据。在Windows环境下,PhantomJS的使用对于开发者来说是十分必要的。 首先,让我们...

    无界面爬虫驱动phantomjs

    python爬虫技术用到的phantomjs驱动,无界面化的浏览器访问

    Python爬虫系列之PhantomJS+Selenium+AutoIt.pptx

    该PPT介绍了Python爬虫在爬取动态网页方面会用到的软件PhantomJS, Selenium, 以及AutoIt. 欢迎对爬虫有兴趣的童鞋进行下载哈,本人亲自制作的PPT~~

    基于Selenium和PhantomJs的Python爬虫

    这是基于Selenium和PhantomJs的Python爬虫,具体可以参考我的博客:http://blog.csdn.net/ProgramChangesWorld/article/details/59489406

    phantomjs1.9.8历史版本用于爬虫

    需要的添加的jar包及工具:我这里使用maven来构建项目,添加依赖如下:  &lt;groupId&gt;org.seleniumhq.selenium ...python版使用webdriver+PhantomJs爬虫使用,参考http://www.cnblogs.com/kuqs/p/6395284.html

    基于C#.NET+PhantomJS+Sellenium的高级网络爬虫系统设计与实现

    《基于C#.NET+PhantomJS+Selenium的高级网络爬虫系统设计与实现》 本文将深入探讨一种高级网络爬虫系统的构建方法,该系统利用C#.NET作为主要开发语言,结合PhantomJS和Selenium工具,实现了高效、稳定且功能强大的...

    C#使用Selenium+PhantomJS抓取数据

    在进行网络爬虫开发时,有时我们需要处理那些依赖JavaScript动态渲染的网页,这时C#结合Selenium与PhantomJS就成为一个有效的解决方案。本文将详细介绍如何在C#环境中利用Selenium WebDriver和PhantomJS来抓取此类...

    phantomjs-2.1.1.zip

    PhantomJS是一个基于Webkit的服务器端JavaScript API,它允许开发者无须浏览器支持即可执行JavaScript、渲染网页并获取结果。2.1.1是PhantomJS的一个版本,它提供了无头浏览器的功能,常用于自动化测试、网页截图、...

    casperjs +phantomjs 爬虫抓包插件

    利用casperjs +phantomjs实现登录抓取网页 并且截图;下载后解压后,在环境变量path中配置解压后bin目录的地址,如:E:\Program Files\casperjs\bin;E:\Program Files\phantomjs\bin

    人工智能-项目实践-C#-基于C#.NET+PhantomJS+Sellenium的高级网络爬虫程序 可执行Javascript

    在本项目实践中,我们探索了如何使用C#.NET框架结合PhantomJS和Selenium构建一个高级的网络爬虫程序,该程序能够处理JavaScript渲染的网页并执行JavaScript代码,从而更全面地获取网络数据。以下是对这个项目的详细...

    phantomjs-2.1.1-windows.zip

    PhantomJS是一个基于Webkit内核的无头浏览器,它允许开发者在没有用户图形界面的情况下运行JavaScript代码,广泛应用于自动化测试、网页截图、网络爬虫等领域。标题"phantomjs-2.1.1-windows.zip"表明这是一个针对...

    一个动态web爬虫_python_JavaScript_代码_下载

    基于CasperJS和PhantomJS,可以自动渲染网页、动态解析js,支持ajax和各类前端交互。 代码基于phantomjs爬虫小记 by wils0n ,在tuicool上也有这篇文章http://www.tuicool.com/articles/JbEfIvV , 原作者的代码在...

    pythonbbs爬虫测试seleuim+phantomjs

    这个基础示例提供了一个起点,帮助你理解Selenium+PhantomJS的组合在爬虫中的应用,以及如何将数据存储到MongoDB。对于新手来说,这是一个很好的学习项目,可以逐步提升对Python爬虫和Web开发的理解。

    Phantomjs无界面浏览器

    6. **爬虫辅助**:在Python中,我们可以使用Selenium库驱动PhantomJS,以便处理需要JavaScript渲染的网页,从而提升爬虫的效率和准确性。 现在,我们来看一下Python中的使用方法。首先,你需要在Python环境中安装...

    网络爬虫 之 PhantomJS技术实战

    本课程使用java作为编程语言,主要内容包括爬虫的基本原理,使用Phantomjs技术抓取拉钩企业招聘信息进行系统分析、Phantomjs的详细使用方法,如何使用Phantomjs分析html代码,基于队列的爬虫、数据存储、数据拆分、...

    phantomjs-2.1.2

    6. **API接口**:PhantomJS提供了一个丰富的API,允许开发者控制页面导航、执行JavaScript、访问DOM元素、处理网络请求等,这些API为自定义自动化任务提供了极大的灵活性。 7. **跨平台**:虽然这里提供的是...

    phantomjs,PhantomJS

    PhantomJS是一个基于webkit的JavaScript API。它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行JavaScript代码。任何你可以在基于webkit浏览器做的事情,它都能做到。它不仅是个隐形的浏览器,提供...

    phantomjs-prebuilt

    3. **网页抓取**:由于支持JavaScript,PhantomJS可以解析动态加载的内容,这使得它成为网络爬虫的理想工具,尤其适合处理那些依赖AJAX技术的网站。 4. **性能测试**:你可以使用PhantomJS来测量网页的加载速度和...

    phantomJS 1.2 jar包

    phantomJS jar包 1.2.1版本 适用于python爬虫 抓取网页

Global site tag (gtag.js) - Google Analytics