def parse_form_action_url(html, parser=None): """Parse <form action="(.+)"> url :param html: str: raw html text :param parser: bs4.BeautifulSoup: html parser :return: url str: for example: /login.php?act=security_check&to=&hash=12346 """ if parser is None: parser = bs4.BeautifulSoup(html, 'html.parser') forms = parser.find_all('form') if not forms: raise VkParseError('No one form is found in \n%s' % html) if len(forms) > 1: raise VkParseError('Find more than 1 forms to handle:\n%s', forms) form = forms[0] return form.get('action')
def do_login(self, http_session): """Do vk login :param http_session: vk_requests.utils.VerboseHTTPSession: http session """ response = http_session.get(self.LOGIN_URL) action_url = parse_form_action_url(response.text) # Stop login it action url is not found if not action_url: logger.debug(response.text) raise VkParseError("Can't parse form action url") login_form_data = {'email': self._login, 'pass': self._password} login_response = http_session.post(action_url, login_form_data) logger.debug('Cookies: %s', http_session.cookies) response_url_query = parse_url_query_params(login_response.url, fragment=False) logger.debug('response_url_query: %s', response_url_query) act = response_url_query.get('act') # Check response url query params firstly if 'sid' in response_url_query: self.require_auth_captcha(query_params=response_url_query, form_text=login_response.text, login_form_data=login_form_data, http_session=http_session) elif act == 'authcheck': self.require_2fa(html=login_response.text, http_session=http_session) elif act == 'security_check': self.require_phone_number(html=login_response.text, session=http_session) session_cookies = ('remixsid' in http_session.cookies, 'remixsid6' in http_session.cookies) if any(session_cookies): logger.info('VK session is established') return True else: message = 'Authorization error: incorrect password or ' \ 'authentication code' logger.error(message) raise VkAuthError(message)
def parse_masked_phone_number(html, parser=None): """Get masked phone number from security check html :param html: str: raw html text :param parser: bs4.BeautifulSoup: html parser :return: tuple of phone prefix and suffix, for example: ('+1234', '89') :rtype : tuple """ if parser is None: parser = bs4.BeautifulSoup(html, 'html.parser') fields = parser.find_all('span', {'class': 'field_prefix'}) if not fields: raise VkParseError( 'No <span class="field_prefix">...</span> in the \n%s' % html) result = [] for f in fields: value = f.get_text().replace(six.u('\xa0'), '') result.append(value) return tuple(result)