(1)环境准备:

请确保已经安装了requests和lxml库

(2)分析登陆过程:

    首先要分析登陆的过程,需要探究后台的登陆请求是怎样发送的,登陆之后又有怎样的处理过程。

     如果已经登陆GitHub,则需要先退出登陆,同时清除Cookies

     打开GitHub的登陆页面,链接为https://github.com/login,输入GitHub的用户名和密码,打开开发者工具

     ,将Preserver Log选项勾选上,这表示持续日志,如下图所示

点击登录按钮,这时便会看到开发者工具下方显示了各个请求过程,如下图所示:

     点击session请求,进入其详情,如下图所示:

可以看到请求的URL为https://www.github.com/session,请求方式为POST。再往下看,我们观察到他的Form Data和Headers这两部分内容,

   如下图所示:

     Headers里面包含了Cookies,Host,Origin,Refer,User-Agent等信息。Form Data包含了5个字段,commit是固定的字符串Sign in,utf8

是一个勾选字符,authenticity_token较长,其初步判断是一个Base64加密的字符串,login是登陆的用户名,password是登陆的密码。

     综上所述,我们现在无法直接构造的内容有Cookies和authenticity_token。下面我们再来探寻一下这部分内容如何获取。

在登陆之前我们会访问到一个登陆页面,此页面是通过GET形式访问的。输入用户名和密码,点击登录按钮,浏览器发送这两部分信息,也就是

说Cookies和authenticity_token一定在访问扥估页面时候设置的。

     这时在退出登陆,回到登录页,同时清除Cookies,重新访问登录页,截获发生的请求,如下图所示:

   

     访问登陆页面的请求如上,Response Headers有一个Set-Cookie字段。这就是设置Cookies的过程。

     另外,我们发现Response Headers没有和authenticity_token相关的信息,所以可能authenticity_token还隐藏在其他的地方或者是计算出来的

。我们再从网页的源码探寻,搜索相关字段,发现源代码里面还隐藏着此信息,他是一个隐藏式表单元素,如下图所示:

     现在我们已经获取到网页所有信息,接下来让我们 实现模拟登陆

(3)代码如下:

 import requests
from lxml import etree class Login(object):
def __init__(self):
self.headers = {
'Refer': 'https://github.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/68.0.3440.75 Safari/537.36',
'Host': 'github.com'
}
self.login_url = 'https://github.com/login'
self.post_url = 'https://github.com/session'
self.logined_url = 'https://github.com/settings/profile'
self.session = requests.Session() # 此函数可以帮助我们维持一个会话,而且可以自动处理cookies,我们不用再去担心cookies的问题 def token(self):
response = self.session.get(self.login_url, headers=self.headers) # 访问GitHub的登录页面
selector = etree.HTML(response.text)
token = selector.xpath('//div//input[2]/@value')[0] # 解析出登陆所需的authenticity_token信息
return token def login(self, email, password):
post_data = {
'commit': 'Sign in',
'utf-8': '✓',
'authenticity_token': self.token(),
'login': email,
'password': password
}
response = self.session.post(self.post_url, data=post_data, headers=self.headers)
if response.status_code == 200:
self.dynamics(response.text) response = self.session.get(self.logined_url, headers=self.headers)
if response.status_code == 200:
self.profile(response.text) def dynamics(self, html): # 使用此方法提取所有动态信息
selector = etree.HTML(html)
dynamics = selector.xpath('//div[contains(@class, "news")]//div[contains(@class, "alert")]')
for item in dynamics:
dynamics = ' '.join(item.xpath('.//div[@class="title"]//text()')).strip()
print(dynamics) def profile(self, html): # 使用此方法提取个人的昵称和绑定的邮箱
selector = etree.HTML(html)
name = selector.xpath('//input[@id="user_profile_name"]/@value')[0]
email = selector.xpath('//select[@id="user_profile_email"]/option[@value!=""]/text()')
print(name, email) if __name__ == "__main__":
login = Login()
login.login(email='', password='') # 此处填自己的

最新文章

  1. apache下htaccess不起作用,linux,windows详解
  2. mysql 常用查询
  3. 领域实体框架Rafy2 发布了
  4. css修改,类似elememt.style样式修改
  5. ajax 、ajax的交互模型、如何解决跨域问题
  6. [转]wireshark 实用过滤表达式(针对ip、协议、端口、长度和内容)
  7. [反汇编练习] 160个CrackMe之027
  8. 转 【O2O案例】汽车后市场垂直化电子商务:平业模式解析
  9. LA 3704 (矩阵快速幂 循环矩阵) Cellular Automaton
  10. 原型模式 - OK
  11. setTimeout和setInterval不容易注意到的一些细节
  12. 【Jsp/Servlet】获取客户端使用的ip
  13. 二十三. Python基础(23)--经典类和新式类
  14. Shell命令 中|| &&使用
  15. vue组件通信之任意级组件之间的通信
  16. 微信小程序学习之for循环
  17. mysql 多个and的简写
  18. require('nw.gui') 失效问题
  19. xamarin.Android SQLite存储
  20. 用canvas播放scratch文件

热门文章

  1. 应用Response.Write实现带有进度条的多文件上传
  2. 1.编译azkaban
  3. BZOJ 3924 ZJOI2015 幻想乡战略游戏 树链剖分
  4. POJ 1269 Intersecting Lines(直线求交点)
  5. Java内存区域划分和GC机制
  6. LintCode-35.翻转链表
  7. WIN8/8.1/10进入BIOS方法图解
  8. [剑指Offer] 53.表示数值的字符串
  9. 在Ubuntu系统下编译arcsim仿真器
  10. 【bzoj2091】[Poi2010]The Minima Game dp