其实我并没有成功,想要模拟人工滑动轨迹骗过验证太难了,我试了好多参数,每次都被拒绝了。我琢磨着是不是要考虑用微积分去设计运动轨迹。。。
思路其实很简单,分别获取完整图片和不完整图片,比较图片的缺口,再将滑块滑到缺口处即可。若要说存在难度的地方,或许就是中间执行了一步js。
如果有哪位大神成功模拟滑动轨迹,烦请赐教。。。
不多说了,上代码。
import time
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
class Bilibili(object):
def __init__(self):
self.url = 'https://passport.bilibili.com/login'
self.browser = webdriver.Chrome()
self.browser.maximize_window()
self.wait = WebDriverWait(self.browser, 10)
self.complete_img = ''
self.incomplete_img = ''
self.slider = ''
self.position = []
self.left = 120
self.track = []
self.main()
def main(self):
self.browser.get(self.url)
self.send_key()
self.get_incomplete_img()
self.get_complete_img()
self.get_gap()
self.set_track()
self.move_to_gap()
self.browser.quit()
def send_key(self):
self.browser.get(self.url)
login = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".btn-login")))
self.browser.find_element_by_id('login-username').send_keys('xxxx')
self.browser.find_element_by_id('login-passwd').send_keys('xxxx')
login.click()
self.slider = WebDriverWait(self.browser, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '.geetest_slider_button')))
def get_incomplete_img(self):
self.browser.save_screenshot('screen.png')
self.incomplete_img = self.browser.find_element_by_css_selector('.geetest_slicebg')
size = self.incomplete_img.size
location = self.incomplete_img.location
top, bottom = 2 * location['y'], 2 * (location['y'] + size['height'])
left, right = 2 * location['x'], 2 * (location['x'] + size['width'])
self.position = [left, top, right, bottom]
self.incomplete_img = Image.open(r'screen.png').crop((left, top, right, bottom))
def get_complete_img(self):
self.change_css_style()
self.browser.save_screenshot('screen.png')
left, top, right, bottom = self.position[0], self.position[1], self.position[2], self.position[3]
self.complete_img = Image.open(r'screen.png').crop((left, top, right, bottom))
def change_css_style(self):
js = 'document.querySelectorAll("canvas")[3].style="display:block"'
self.browser.execute_script(js)
time.sleep(1)
def get_gap(self):
for ii in range(self.left, self.incomplete_img.size[0]):
for jj in range(self.complete_img.size[1]):
if not self.compare_img(ii, jj):
self.left = round(ii / 2 - 8)
return
def compare_img(self, x, y, gap=60):
pixel1 = self.incomplete_img.load()[x, y]
pixel2 = self.complete_img.load()[x, y]
if abs(pixel1[0] - pixel2[0]) < gap and abs(pixel1[1] - pixel2[1]) < gap and abs(pixel1[2] - pixel2[2]) < gap:
return True
else:
return False
def set_track(self):
mid = 0.8 * self.left
current = 0
t = 0.2
v = 0
while current < self.left:
if current < mid:
a = 2
else:
a = -3
v0 = v
v = v0 + a * t
move = v0 * t + 1 / 2 * a * t * t
current += move
self.track.append(round(move))
def move_to_gap(self):
ActionChains(self.browser).click_and_hold(self.slider).perform()
for each_move in self.track:
if each_move == 0:
continue
ActionChains(self.browser).move_by_offset(xoffset=each_move, yoffset=0).perform()
time.sleep(0.5)
ActionChains(self.browser).release().perform()
if __name__ == '__main__':
spider = Bilibili()