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()

     

 

posted @ 2021-07-18 11:35  BulletsintheBible  阅读(106)  评论(0)    收藏  举报