Python Github自动登录,Github开源项目分析

一、前言

Github源码链接:https://github.com/Python3WebSpider/GithubLogin
崔庆才:https://cuiqingcai.com/8229.html

说到自动登录,用selenium是最合适的了,之前也实战了几次。这回来尝试一下构造post表单,利用post请求登录。

二、分析

)登录过程

在此之前,首先要搞清楚什么是Cookies和Session。Cookies和Session都保存了个人用户的信息,不同的是,Cookies保存在客户端,也就是自己的电脑,而Session保存在服务器端。

既然都是保存用户信息的,为什么会出现两个东西呢?

其一保存在客户端的Cookies可以分担服务器的工作,其二在Cookies里保存了SessionID的信息,在post请求后会发送Cookies给服务器,服务器根据SessionID,找到对应的Session,找到后即登录成功。

Cookies的问题可以使用requests.Session()来维持一个会话,可以自动处理Cookies。

)构造表单

为了弄清楚表单的内容是什么,里面的信息和之前的请求有什么联系,先清除浏览器里github相关的Cookies,然后访问登录页
面:https://github.com/login。登录后查看一下session:

在这里插入图片描述
多登录几次可以发现,login和password字段是之前输入的用户名和密码,authenticity_token字段很乱且每次都不一样,timestamp是时间戳不必管,其它字段都是一样的。所以要解决的只有authenticity_token字段。

既然这个字段也是在表单里提交上去的,那它可能也和用户名和密码一样,在登录网页就有(https://github.com/login)。

如果之前点了保存日志,那么还可以看到login的请求和相应。
在这里插入图片描述
但是看不了登录页面的代码,所以我用了Fiddler,它在分析多个网页时很有用。
(关于Fiddler的安装和使用:https://www.bookstack.cn/read/piaosanlang-spiders/c10f6ef032db5d49.md

在这里插入图片描述
观察请求和响应,并没有authenticity_token字段的信息。那么看一下网页代码里面有没有:

在这里插入图片描述1111
找到了!name属性为input的结点,它的value属性就是这个字段对应的信息。与session里的表单比对一下:

在这里插入图片描述
是一样的没错,所以在构造表单的时候只要解析/login网页,找到authenticity_token对应的value即可。

三、代码

)相关依赖

from pyquery.pyquery import PyQuery as pq
from requests.packages import urllib3
import requests

)构造函数

定义一个Github类,并初始化一些变量

class Github:
    def __init__(self):
        """
        初始化

        """
        urllib3.disable_warnings()
        self.login_url = 'https://github.com/login'
        self.post_url = 'https://github.com/session'
        # 个人主页
        self.self_url = 'https://github.com/Pineapple666'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'
        }
        self.session = requests.Session()

)获取字段信息

    def token(self):
        """
        获取authenticity_token字段信息

        :return: None
        """
        response = self.session.get(url=self.login_url, headers=self.headers, verify=False)
        if response.status_code == 200:
            html = response.text
            doc = pq(html)
            return doc('input[name="authenticity_token"]').attr('value')
        else:
            print(f'response status code = {response.status_code}')

在下面的构造表单中返回这个函数

)构造表单并登录

    def login(self, username, password):
        """
        提交表单,登录

        :param username: 用户名
        :param password: 密码
        :return: None
        """
        post_data = {
            'webauthn-iuvpaa-support': 'supported',
            'authenticity_token': self.token(),
            'webauthn-support': 'supported',
            'required_field_b538': None,
            'password': password,
            'commit': 'Sign in',
            'login': username,
            'return_to': None,
        }
        response = self.session.post(url=self.post_url, data=post_data, headers=self.headers)
        if response.status_code == 200:
            print('login in successful!')
        else:
            print(f'response status code = {response.status_code}')

)测试登录成功

    def test(self):
        """
        测试登录成功,输出用户ID

        :return: None
        """
        response = self.session.get(url=self.self_url, headers=self.headers, verify=False)
        if response.status_code == 200:
            html = response.text
            doc = pq(html)
            id = doc('span[itemprop="additionalName"]').text()
            print(f'your id is {id}')
        else:
            print(f'response status code = {response.status_code}')

)完整代码

# -*- coding: utf-8 -*-
"""
@author     :Pineapple

@Blog       :https://blog.csdn.net/pineapple_C

@contact    :cppjavapython@foxmail.com

@time       :2020/8/19 8:50

@file       :github.py

@desc       :
"""
from pyquery.pyquery import PyQuery as pq
from requests.packages import urllib3
import requests


class Github:
    def __init__(self):
        """
        初始化

        """
        urllib3.disable_warnings()
        self.login_url = 'https://github.com/login'
        self.post_url = 'https://github.com/session'
        # 个人主页
        self.self_url = 'https://github.com/Pineapple666'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'
        }
        self.session = requests.Session()

    def login(self, username, password):
        """
        提交表单,登录

        :param username: 用户名
        :param password: 密码
        :return: None
        """
        post_data = {
            'webauthn-iuvpaa-support': 'supported',
            'authenticity_token': self.token(),
            'webauthn-support': 'supported',
            'required_field_b538': None,
            'password': password,
            'commit': 'Sign in',
            'login': username,
            'return_to': None,
        }
        response = self.session.post(url=self.post_url, data=post_data, headers=self.headers)
        if response.status_code == 200:
            print('login in successful!')
        else:
            print(f'response status code = {response.status_code}')

    def token(self):
        """
        获取authenticity_token字段信息

        :return: None
        """
        response = self.session.get(url=self.login_url, headers=self.headers, verify=False)
        if response.status_code == 200:
            html = response.text
            doc = pq(html)
            return doc('input[name="authenticity_token"]').attr('value')
        else:
            print(f'response status code = {response.status_code}')

    def test(self):
        """
        测试登录成功,输出用户ID

        :return: None
        """
        response = self.session.get(url=self.self_url, headers=self.headers, verify=False)
        if response.status_code == 200:
            html = response.text
            doc = pq(html)
            id = doc('span[itemprop="additionalName"]').text()
            print(f'your id is {id}')
        else:
            print(f'response status code = {response.status_code}')


if __name__ == '__main__':
    username = input('username:')
    password = input('password:')
    github = Github()
    github.login(username, password)
    github.test()

)输出

在这里插入图片描述

posted @ 2022-04-06 14:48  王舰  阅读(305)  评论(0编辑  收藏  举报