爬虫逆向滑块验证

selenium滑动验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import time
from selenium import webdriver
from selenium.webdriver.common.by import By # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait # 等待页面加载某些元素
import cv2 #pip install opencv-python

from urllib import request
from selenium.webdriver.common.action_chains import ActionChains


#获取要滑动的距离
def get_distance():
#滑动验证码的整体背景图片
background = cv2.imread("background.png", 0)
#缺口图片
gap = cv2.imread("gap.png", 0)

res = cv2.matchTemplate(background, gap, cv2.TM_CCOEFF_NORMED)
value = cv2.minMaxLoc(res)[2][0]
print(value)
#单位换算
return value * 278 / 360


def main():
chrome = webdriver.Chrome(executable_path='./chromedriver')
chrome.implicitly_wait(5)

chrome.get('https://passport.jd.com/new/login.aspx?')

login = chrome.find_element(By.ID, 'pwd-login')
login.click()

loginname = chrome.find_element(By.ID, 'loginname')
loginname.send_keys("xxxx")

nloginpwd = chrome.find_element(By.ID, 'nloginpwd')
nloginpwd.send_keys("xxxxx")

loginBtn = chrome.find_element(By.CLASS_NAME, 'login-btn')
loginBtn.click()
#带缺口的大图
img_src = chrome.find_element(By.XPATH, '//*[@class="JDJRV-bigimg"]/img').get_attribute("src")
#缺口图片
temp_src = chrome.find_element(By.XPATH, '//*[@class="JDJRV-smallimg"]/img').get_attribute("src")
#两张图片保存起来
request.urlretrieve(img_src, "background.png")
request.urlretrieve(temp_src, "gap.png")

distance = int(get_distance())
print("distance:", distance)

print('第一步,点击滑动按钮')
element = chrome.find_element(By.CLASS_NAME, 'JDJRV-slide-btn')
ActionChains(chrome).click_and_hold(on_element=element).perform() # 点击鼠标左键,按住不放

ActionChains(chrome).move_by_offset(xoffset=distance, yoffset=0).perform()
ActionChains(chrome).release(on_element=element).perform()

time.sleep(2)
if __name__ == '__main__':
main()

pyppeteer滑动验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import random
from pyppeteer import launch
import asyncio
import cv2
from urllib import request


async def get_track():
background = cv2.imread("background.png", 0)
gap = cv2.imread("gap.png", 0)

res = cv2.matchTemplate(background, gap, cv2.TM_CCOEFF_NORMED)
value = cv2.minMaxLoc(res)[2][0]
return value * 278 / 360 - 13

async def main():
browser = await launch({
# headless指定浏览器是否以无头模式运行,默认是True。
"headless": False,
#设置窗口大小
"args": ['--window-size=1366,768'],
"executablePath" : '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
})
# 打开新的标签页
page = await browser.newPage()
# 设置页面大小一致
await page.setViewport({"width": 1366, "height": 768})
# 访问主页
await page.goto("https://passport.jd.com/new/login.aspx?")


# 模拟输入用户名和密码,输入每个字符的间隔时间delay ms
await page.type("#loginname", '', {
"delay": random.randint(30, 60)
})
await page.type("#nloginpwd", '', {
"delay": random.randint(30, 60)
})

# page.waitFor 通用等待方式,如果是数字,则表示等待具体时间(毫秒): 等待2秒
await page.waitFor(2000)
await page.click("div.login-btn")
await page.waitFor(2000)
# page.Jeval(selector,pageFunction)#定位元素,并调用js函数去执行
#=>表示js的箭头函数:el = function(el){return el.src}
img_src = await page.Jeval(".JDJRV-bigimg > img", "el=>el.src")
temp_src = await page.Jeval(".JDJRV-smallimg > img", "el=>el.src")

request.urlretrieve(img_src, "background.png")
request.urlretrieve(temp_src, "gap.png")

# 获取gap的距离
distance = await get_track()
"""
# Pyppeteer 三种解析方式
Page.querySelector() # 选择器
Page.querySelectorAll()
Page.xpath() # xpath 表达式
# 简写方式为:
Page.J(), Page.JJ(), and Page.Jx()
"""
#定位到滑动按钮标签
el = await page.J("div.JDJRV-slide-btn")
# 获取元素的边界框,包含x,y坐标
box = await el.boundingBox()
#box={'x': 86, 'y': 34, 'width': 55.0, 'height': 55.0}
#将鼠标悬停/一定到指定标签位置
await page.hover("div.JDJRV-slide-btn")
#按下鼠标
await page.mouse.down()
#模拟人的行为进行滑动
# steps 是指分成几步来完成,steps越大,滑动速度越慢
#move(x,y)表示将鼠标移动到xy坐标位置
#random.uniform生成指定范围的随机浮点数
await page.mouse.move(box["x"] + distance + random.uniform(20, 40),
box["y"],
{"steps": 100})
await page.waitFor(1000)

await page.mouse.up()
await page.waitFor(2000)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())


爬虫逆向滑块验证
http://example.com/2023/12/21/爬虫逆向滑块验证/
Author
John Doe
Posted on
December 21, 2023
Licensed under