python爬虫小白升仙_7-----selenium模拟登录豆瓣网+opencv破解滑块验证码

使用selenium进行模拟登录豆瓣网,利用opencv模块获取滑块验证码的缺口,最终实现模拟登录

涉及

1. selenim启动360极速浏览器

2. selenium获取标签、输入等的基本操作

3. 获取登录相关标签时,遇iframe的解决办法

3. 获取滑块验证码图片,并下载到本地

4. 使用opencv模块中的"模板匹配"方法获取缺口的位置

5. 采用物理加速度位移相关公式按照先快后慢的人工滑动规律模拟滑块运动轨迹

6. selenium滑块操作

流程

1. 访问主页

 

2. 切换到密码登录页

3. 输入账号、密码,点击登录

4. 错误登录几次后会出现滑块验证码

5. 破解滑块验证码,使验证通过

详解

  • selenim启动360极速浏览器

1. 下载360极速浏览器对应的Chromedriver,下载请点击,内核版本查询见下图

2. 将下载的Chromedriver.exe放到360chrome.exe所在目录下以及pythonw.exe所在目录

3. 添加系统环境变量path:F:\360Chrome\Chrome\Application\360chrome.exe

4. 初始化driver

browser_url = r'F:\360Chrome\Chrome\Application\360chrome.exe'
chrome_options = Options()
chrome_options.binary_location = browser_url
# 声明浏览器对象
driver = webdriver.Chrome(chrome_options=chrome_options)

# 登录豆瓣
# 访问页面
driver.get('https://www.douban.com')
  • selenium常用操作

1. 详细操作参考:详细说明

2. 输入账号、密码

# 通过类名查找  若遇到复合类(即中间有空格)class='account-tab-account on',选取其中一个类即可,#若其再html中不唯一,可采用[index]定位
driver.find_element_by_class_name("account-tab-account").click()
driver.find_element_by_id('username').send_keys('12345678')
driver.find_element_by_id('password').send_keys('qwertyu')
time.sleep(2)
driver.find_element_by_class_name('btn-account').click()
  • iframe获取

1. iframe,又叫浮动帧标记,是内嵌的网页元素,可以将一个html文件嵌入到另一个html文件中显示。

# switch_to.frame() 切换到iframe上

# switch_to.default_content() 切换回原主页面

# 定位到iframe   #通过contains函数,提取匹配特定文本的元素
    iframe=driver.find_element_by_xpath("//iframe[contains(@src,'//accounts.douban.com/passport/login_popup?login_source=anony')]")
    # 切换到iframe
    driver.switch_to.frame(iframe)
# 定位到滑块验证码的iframe
slider_iframe = driver.find_element_by_xpath('//div[@id="TCaptcha"]/iframe[1]')
# 切换到iframe
driver.switch_to.frame(slider_iframe)
  • 获取滑块验证码图片,并下载到本地

1. 获取验证码图片

# 获取背景图和滑块图的url
background_image_url=driver.find_element_by_id('slideBkg').get_attribute('src')
slider_image_url=driver.find_element_by_id('slideBlock').get_attribute('src')
# 下载图片到本地
def get_image(img_url,imgname):
    # 以流的形式下载文件
    image=requests.get(img_url,stream=True)
    # str.join()方法用于将序列中的元素以指定的字符(str)连接生成一个新的字符串
    imgName = ''.join(["./", imgname])
    with open(imgName, 'wb') as f:
        for chunk in image.iter_content(chunk_size=1024): # 循环写入  chunk_size:每次下载的数据大小
            if chunk:
                f.write(chunk)
                f.flush()
        f.close()
  • 使用opencv模块中的"模板匹配"方法获取缺口的位置
# 使用opencv模块 计算缺口的偏移值
def get_image_offset(background_image_url,slider_image_url):
    back_image='back_image.png'   # 背景图像命名
    slider_image='slider_image.png'  # 滑块图像命名
    get_image(background_image_url,back_image)
    get_image(slider_image_url,slider_image)
    # 获取图片并灰度化
    block=cv2.imread(slider_image,0)
    template=cv2.imread(back_image,0)
    w,h=block.shape[::-1]
    print(w,h)
    # 二值化后图片名称
    block_name='block.jpg'
    template_name='template.jpg'
    # 保存二值化后的图片
    cv2.imwrite(block_name,block)
    cv2.imwrite(template_name,template)
    block=cv2.imread(block_name)
    block=cv2.cvtColor(block,cv2.COLOR_RGB2GRAY)
    block=abs(255-block)
    cv2.imwrite(block_name,block)
    block=cv2.imread(block_name)
    template=cv2.imread(template_name)
    # 获取偏移量
    # 模板匹配,查找block在template中的位置,返回result是一个矩阵,是每个点的匹配结果
    result=cv2.matchTemplate(block,template,cv2.TM_CCOEFF_NORMED)
    x,y=np.unravel_index(result.argmax(),result.shape)
    print(x,y)
    # 由于获取到的验证码图片像素与实际的像素有差(实际:280*158 原图:680*390),故对获取到的坐标进行处理
    offset=y*(280/680)
    # 画矩形圈出匹配的区域
    # 参数解释:1.原图 2.矩阵的左上点坐标 3.矩阵的右下点坐标 4.画线对应的rgb颜色 5.线的宽度
    cv2.rectangle(template, (y, x), (y + w, x + h), (7, 249, 151), 2)
    show(template)
    return offset

# 显示图片
def show(name):
	cv2.imshow('Show', name)
	cv2.waitKey(0)
	cv2.destroyAllWindows()
  • 模拟运动轨迹
# 采用物理加速度位移相关公式按照先快后慢的人工滑动规律进行轨迹计算,
# 同时还采用了模拟人滑动超过了缺口位置再滑回至缺口的情况以使轨迹更契合人工滑动轨迹
def get_track(distance):
	track = []
	current = 0
	mid = distance * 3 / 4
	t=random.randint(2,3)/10
	v = 0
	while current < distance:
		if current < mid:
			a = 2
		else:
			a = -3
		v0 = v
		v = v0 + a * t
		move = v0 * t + 1 / 2 * a * t * t
		current += move
		track.append(round(move,2))
	return track
  • selenium滑块操作
# 定位到滑块按钮
    button=driver.find_element_by_id('tcaptcha_drag_thumb')
    # 拖动操作用到ActionChains类,实例化
    action=ActionChains(driver)
    # perform()用来执行ActionChains中存储的行为
    action.click_and_hold(button).perform()
    # 清除之前的action
    action.reset_actions()
    # 获取轨迹
    track=get_track(distance+random.randint(3,5))
    print(track)
    sum=0
    for i in track:
        sum+=i
    print(sum)
    for i in track:
        action.move_by_offset(xoffset=i,yoffset=0).perform()
        action.reset_actions()
    time.sleep(1)
    action.release().perform()

    time.sleep(3)
    driver.quit()

运行结果:

识别率还ok,代码写的比较粗糙,后续处理别的网站再进行细节优化

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
首先,为了访问QQ空间相册,我们需要登录QQ账号。可以使用Selenium模拟用户登录QQ,然后使用BeautifulSoup解析相册页面,获取相册的图片链接。 以下是大致的实现步骤: 1. 安装Selenium和BeautifulSoup模块。 2. 使用Selenium模拟用户登录QQ,进入相册页面。 ```python from selenium import webdriver # 创建Chrome浏览器对象 browser = webdriver.Chrome() # 打开QQ登录页面 browser.get("https://mail.qq.com/") # 执行模拟登录操作,具体实现可以参考Selenium文档或其他相关教程 # ... # 进入相册页面 browser.get("http://user.qzone.qq.com/123456789/album") ``` 3. 使用BeautifulSoup解析相册页面,获取相册的图片链接。 ```python from bs4 import BeautifulSoup # 获取相册页面的HTML源代码 html = browser.page_source # 使用BeautifulSoup解析HTML源代码,获取相册的图片链接 soup = BeautifulSoup(html, "html.parser") img_links = soup.find_all("img", class_="c_photo_img_img") # 打印图片链接 for link in img_links: print(link["src"]) ``` 4. 下载图片。 ```python import requests # 下载图片 for i, link in enumerate(img_links): img_url = link["src"] response = requests.get(img_url) with open(f"photo_{i}.jpg", "wb") as f: f.write(response.content) ``` 以上只是大致的实现步骤,具体的实现过程可能还需要根据实际情况进行调整。同时,需要注意的是,访问QQ空间相册需要登录QQ账号,因此需要注意账号安全问题。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值