利用Python模拟GitHub登陆

最近学习了Fiddler抓包工具的简单使用,经过抓包,咱们能够抓取到HTTP请求,并对其进行分析。如今我准备尝试着结合Python来模拟GitHub登陆。html

Fiddler抓包分析

首先,咱们想要模拟一个网站的登陆,咱们必需要简单了解其大体过程。
在这里,我经过Fiddler来抓取GitHub登陆的请求,从网页上登陆的URL为:https://github.com/login ,抓包结果以下:git

左边的是会话列表,右边的是请求和响应的数据。通常状况下,登陆都是用POST请求,由于我在左边的会话列表中设置了显示RequestMethod一列,所以可以很方便的找到POST请求。固然,Fiddler默认不显示RequestMethod,若是没有设置,还能够经过命令“=post”来快速过滤POST请求。github

在GitHub登陆时,咱们经过抓包发现,GitHub登陆的URL虽然时https://github.com/login,但发生了302重定向,其真正提交POST表单数据的URL是 https://github.com/session ,当登陆成功时,则会跳转到 https://github.com/ 首页。web

打开WebForm,咱们能够看到POST表单数据提交的值,能够发现,只有authenticity_token、login、password三个字段是会变化的,其他的每次登陆都是固定的值。而login、password分别是咱们登陆的用户和密码,所以咱们只须要分析出 authenticity_token 从何而来,即可以实现模拟登陆了。正则表达式

至于如何肯定 authenticity_token 从哪一个页面返回的,咱们直接在响应数据中搜索就好了,或者把数据复制出来再进行搜索。最后咱们会发现,authenticity_token 是在 https://github.com/login 这个请求中返回的,只不过用 hidden 隐藏起来了。浏览器

好了,到目前大体流程咱们已经梳理清楚了,接下来咱们便经过Python来实现模拟GitHub登陆。cookie

代码实现

本人环境:PyCharm 2018.2.四、Python3.7.0session

1. 设置请求头和Session

# 设置Session
        self.s = requests.session()
        # 设置请求头
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:44.0) Gecko/20100101 Firefox/44.0"
        }
        # 在使用Fiddler时进行请求,经过该代码忽略SSLError错误
        self.s.verify = False

在这里,咱们设置了Session会话对象,Session至关于1个微型浏览器,可以自动帮咱们保持请求中的某些参数(如cookies),有了它,咱们通常不须要额外去处理cookies、header等。
假如咱们是在Fiddler打开的状态下,经过代码进行请求,那么将会遇到SSLError的错误,而当加上 self.s.verify = False 这行代码后,咱们即可以忽略该错误。工具

requests.exceptions.SSLError: HTTPSConnectionPool(host='github.com', port=443): Max retries exceeded with url: /login (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)')))

注意:
咱们经过上面的代码忽略了SSLError的错误后,再次运行,这时仍然会出现2行警告,这2个警告并不影响咱们的登陆,能够无论它。post

D:\Python\installation\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
D:\Python\installation\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

若是咱们想去掉这2行警告,也能够经过以下代码来解决(针对Python3):

import urllib3
urllib3.disable_warnings()

2. 获取authenticity_token

login_url = "https://github.com/login"
        r = self.s.get(login_url, headers = self.headers)
        authenticity_token = re.findall('<input type="hidden" name="authenticity_token" value="(.+?)" />', r.text)
        print("authenticity_token:{}".format(authenticity_token))
        return authenticity_token[1]

当咱们访问 https://github.com/login 时,登陆界面会生成隐藏参数authenticity_token,而这恰是咱们在登陆提交表单时须要用到的参数。咱们可经过正则表达式 re.findall 来获取authenticity_token。另外,咱们还会发现,HTML界面中存在2个authenticity_token,所以经过正则返回的是一个长度为2的列表,通过分析,GitHub在登陆时用到的是列表中的第二个元素,即authenticity_token[1]。

3. 模拟登陆

def github_login(self, authenticity_token, username, password):
        session_url = "https://github.com/session"
        body = {
            "authenticity_token":authenticity_token,
            "commit":"Sign in",
            "login":username,
            "password":password,
            "utf8":"✓",
            "webauthn-support":"unknown"
        }
        r = self.s.post(session_url, headers = self.headers, data = body)
        title = re.findall('<title>(.+?)</title>',r.text)
        print("title:%s" %title[0])
        return title[0]

咱们在上面获得authenticity_token后,即可以来实现登陆了。经过POST请求提交表单后,咱们须要判断是否登陆成功。在这里,我是经过页面的标题来判断GitHub是否登陆成功,固然,还有许多方法能够用于判断。

4. 经过 title 判断是否登陆成功

def is_login_success(self, title):
        if "GitHub" == title:
            return True
        else:
            return False

GitHub登陆成功后,界面的标题会显示"GitHub",而登陆失败时,通常显示的标题则是"Sign in to GitHub · GitHub"。

OK,以上就是经过Python模拟GitHub登陆的过程,难度不大,相信大多数人阅读后都应该能够进行实践。

附源码:

import requests
import re
import urllib3
urllib3.disable_warnings()

class Github_Login():

    def __init__(self):
        # 设置Session
        self.s = requests.session()
        # 设置请求头
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:44.0) Gecko/20100101 Firefox/44.0"
        }
        # 在使用Fiddler时进行请求,经过该代码忽略SSLError错误
        self.s.verify = False

    # 获取 authenticity_token
    def get_authenticity_token(self):
        login_url = "https://github.com/login"
        r = self.s.get(login_url, headers = self.headers)
        authenticity_token = re.findall('<input type="hidden" name="authenticity_token" value="(.+?)" />', r.text)
        print("authenticity_token:{}".format(authenticity_token))
        return authenticity_token[1]

    # 模拟登陆,并返回 title
    def github_login(self, authenticity_token, username, password):
        session_url = "https://github.com/session"
        body = {
            "authenticity_token":authenticity_token,
            "commit":"Sign in",
            "login":username,
            "password":password,
            "utf8":"✓",
            "webauthn-support":"unknown"
        }
        r = self.s.post(session_url, headers = self.headers, data = body)
        title = re.findall('<title>(.+?)</title>',r.text)
        print("title:%s" %title[0])
        return title[0]

    # 经过 title 判断是否登陆成功
    def is_login_success(self, title):
        if "GitHub" == title:
            return True
        else:
            return False

if __name__ == '__main__':
    github = Github_Login()
    authenticity_token = github.get_authenticity_token()
    title = github.github_login(authenticity_token, username = "用户名", password = "密码")
    login_result = github.is_login_success(title)
    print(login_result)

若有错误,欢迎指出!

相关文章
相关标签/搜索