selenium模拟登录12306
使用selenium登录
1.防检测
- 12306识别出window.navigator.webdriver,所以只需
# 2.如果chrome版本大于88 option = Options() option.add_argument('--disable-blink-features=AutomationControlled')
2.打开目标地址
def open(self): """打开网页输入用户密码""" self.browser.get(self.url) # 点击账号登录 logging.info('打开浏览器获取网页') time.sleep(3) # 睡眠3秒,因为在网页加载时候,登录按钮并未完全加载成功。 self.wait.until(EC.presence_of_element_located((By.XPATH, '//li[@class="login-hd-account"]/a'))).click() # 输入用户名和密码 username = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@class="input"][position()=1]'))) password = self.wait.until(EC.presence_of_element_located((By.XPATH, '//input[@type="password"]'))) username.send_keys(self.username) time.sleep(1) password.send_keys(self.password) time.sleep(1) logging.info('登录成功')
- 获取验证码按钮
def get_captcha_button(self): """获取验证码t图片对象""" element = self.wait.until(EC.presence_of_element_located((By.XPATH, '//img[@id="J-loginImg"]'))) time.sleep(1) logging.info('验证码获取') return element
- 超级鹰解析验证码
def parse_captcha(self): """使用超级鹰解析网页""" # self.get_captcha_image() # 调用保存图片 # 识别验证码 result = chaojiying.PostPic(self.get_captcha_button().screenshot_as_png, 9004) print(result) return result
chaojiying.PostPic主要接受两个参数,一个是二进制数据,一个是验证码的难度。获取验证码的二进制方法有两个,获取按钮,直接使用screenshot_as_png,获取屏幕截图,保存的是二进制数据。第二,精确验证码的位置,使用screenshot_as_png得到精确二维码的二进制数值,使用Image.open(BytesIo())以二进制解码后打开方法打开图片,再.crop精确到验证码的位置,最后保存到本地目录。
def get_captcha_image(self): """获取网页截图""" screenshot = self.get_captcha_button.get_screenshot_as_png() i = Image.open(BytesIO(screenshot)) coordinates = self.get_captcha_position() # 调用截取位置 screenshot = i.crop(coordinates) screenshot.save('screenshot.png') return screenshot
- 解析平台返回结果,其平台返回的结果形式:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '2077320412830000020','pic_str': '60,19|109,16|187,92', 'md5': 'c3d41675003cd44058347e591cf405e7'}其中pic_str是返回的坐标,
def get_points(self): """解析识别结果""" result = self.parse_captcha() # 调用平台返回结果 groups = result.get('pic_str').split('|') # 其中以|为分割,分成['60,19','109,16','187,92'],变为列表类型 locations = [[int(number) for number in group.split(',')] for group in groups] # for group in groups是最外层的遍历,以,为分割,将结果变为整型,返回的['60','19'] print(locations) return locations
点击事件到平台返回位置
def touch_click_words(self): """移动目标""" locationts = self.get_points() # 调用处理解析识别结果 for rs in locationts: x = int(rs[0]) # x的坐标 y = int(rs[1]) print(x, y) element = self.get_captcha_button() time.sleep(2) ActionChains(self.browser).move_to_element_with_offset(element, x, y).click().perform() # 点击事件需要提交 time.sleep(1) logging.info('logging successly')
move_to_element_with_offse带着偏移量移动到某个位置。坐标系为右是x。x是y。
def login(self): self.browser.find_element_by_xpath('//*[@id="J-login"]').click() # 点击登录按钮 time.sleep(2) # 拖拽按钮 btn = self.browser.find_element_by_xpath('//*[@id="nc_1_n1z"]') # 找到按钮图标 ActionChains(self.browser).drag_and_drop_by_offset(btn, 300, 0).perform() # 拖拽按钮到300位置
-
函数运行
if __name__ == '__main__': u = CrackCaptcha() u.open() u.touch_click_words() u.login()
浙公网安备 33010602011771号