Python爬虫学习笔记之模拟登陆并爬去GitHub
(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='') # 此处填自己的
最新文章
- apache下htaccess不起作用,linux,windows详解
- mysql 常用查询
- 领域实体框架Rafy2 发布了
- css修改,类似elememt.style样式修改
- ajax 、ajax的交互模型、如何解决跨域问题
- [转]wireshark 实用过滤表达式(针对ip、协议、端口、长度和内容)
- [反汇编练习] 160个CrackMe之027
- 转 【O2O案例】汽车后市场垂直化电子商务:平业模式解析
- LA 3704 (矩阵快速幂 循环矩阵) Cellular Automaton
- 原型模式 - OK
- setTimeout和setInterval不容易注意到的一些细节
- 【Jsp/Servlet】获取客户端使用的ip
- 二十三. Python基础(23)--经典类和新式类
- Shell命令 中|| &;&;使用
- vue组件通信之任意级组件之间的通信
- 微信小程序学习之for循环
- mysql 多个and的简写
- require('nw.gui') 失效问题
- xamarin.Android SQLite存储
- 用canvas播放scratch文件
热门文章
- 应用Response.Write实现带有进度条的多文件上传
- 1.编译azkaban
- BZOJ 3924 ZJOI2015 幻想乡战略游戏 树链剖分
- POJ 1269 Intersecting Lines(直线求交点)
- Java内存区域划分和GC机制
- LintCode-35.翻转链表
- WIN8/8.1/10进入BIOS方法图解
- [剑指Offer] 53.表示数值的字符串
- 在Ubuntu系统下编译arcsim仿真器
- 【bzoj2091】[Poi2010]The Minima Game dp