Python爬虫-模拟Github登录并获取个人信息

简介: python爬虫案例,模拟登录Github

前言

很多情况下,页面的某些信息需要登录才可以查看。对于爬虫来说,需要爬取的信息如果需要登录才可以看到的话,那么我们就需要做一些模拟登录的事情。

在前面我们了解了会话和 Cookies 的用法。简单来说,打开网页然后模拟登录,这实际上是在客户端生成了 Cookies,而 Cookies 里面保存了 SessionID 的信息,登录之后的后续请求都会携带生成后的 Cookies 发送给服务器。服务器就会根据 Cookies 判断出对应的 SessionID,进而找到会话。如果当前会话是有效的,那么服务器就判断用户当前已经登录了,返回请求的页面信息,这样我们就可以看到登录之后的页面。

这里的核心就是获取登录之后的 Cookies。而要获取 Cookies,我们可以手动在浏览器里输入用户密码,然后再把 Cookies 复制下来,但是这样做明显会增加人工工作量。爬虫的目的不就是自动化吗?所以我们要做的就是用程序来完成这个过程,也就是用程序模拟登录。

接下来,我们将介绍模拟登录的相关方法以及如何维护一个 Cookies 池。

实战

我们以一个简单的实例来了解模拟登录后页面的抓取过程,其原理在于模拟登录后 Cookies 的维护。

1. 本节目标

本节将讲解以 GitHub 为例来实现模拟登录的过程,同时爬取登录后才可以访问的页面信息,如好友动态、个人信息等内容。

我们应该都听说过 GitHub,如果在我们在 Github 上关注了某些人,在登录之后就会看到他们最近的动态信息,比如他们最近收藏了哪个 Repository,创建了哪个组织,推送了哪些代码。但是退出登录之后,我们就无法再看到这些信息。

如果希望爬取 GitHub 上所关注人的最近动态,我们就需要模拟登录 GitHub。

2. 环境准备

请确保已经安装好了 requests 和 lxml 库,如没有安装请参考Python爬虫请求库安装#1-CSDN博客

3. 分析登录过程

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

如果已经登录 GitHub,先退出登录,同时清除 Cookies。

打开 GitHub 的登录页面,链接为 Sign in to GitHub · GitHub,输入 GitHub 的用户名和密码,打开开发者工具,将 Preserve Log 选项勾选上,这表示显示持续日志。

image.gif 编辑

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

image.gif 编辑

点击第一个请求,进入其详情页面。

image.gif 编辑

可以看到请求的 URL 为 Sign in to GitHub · GitHub,请求方式为 POST。再往下看,我们观察到它的 Form Data 和 Headers 这两部分内容。

image.gif 编辑

Headers 里面包含了 Cookies、Host、Origin、Referer、User-Agent 等信息。Form Data 包含了 5 个字段,commit 是固定的字符串 Sign in,utf8 是一个勾选字符,authenticity_token 较长,其初步判断是一个 Base64 加密的字符串,login 是登录的用户名,password 是登录的密码。

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

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

这时再退出登录,回到登录页,同时清空 Cookies,重新访问登录页,截获发生的请求。

image.gif 编辑

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

另外,我们发现 Response Headers 没有和 authenticity_token 相关的信息,所以可能 authenticity_token 还隐藏在其他的地方或者是计算出来的。我们再从网页的源码探寻,搜索相关字段,发现源代码里面隐藏着此信息,它是一个隐藏式表单元素。

image.gif 编辑

现在我们已经获取到所有信息,接下来实现模拟登录。

4. 代码实战

首先我们定义一个 Login 类,初始化一些变量:

class Login(object):

   def __init__(self):

       self.headers = {

           'Referer': 'https://github.com/',

           'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 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()

这里最重要的一个变量就是 requests 库的 Session,它可以帮助我们维持一个会话,而且可以自动处理 Cookies,我们不用再去担心 Cookies 的问题。

接下来,访问登录页面要完成两件事:一是通过此页面获取初始的 Cookies,二是提取出 authenticity_token。

在这里我们实现一个 token() 方法,如下所示:

from lxml import etree


def token(self):

   response = self.session.get(self.login_url, headers=self.headers)

   selector = etree.HTML(response.text)

   token = selector.xpath('//div/input[2]/@value')[0]

   return token

我们用 Session 对象的 get() 方法访问 GitHub 的登录页面,然后用 XPath 解析出登录所需的 authenticity_token 信息并返回。

现在已经获取初始的 Cookies 和 authenticity_token,开始模拟登录,实现一个 login() 方法,如下所示:

def login(self, email, password):

   post_data = {

       'commit': 'Sign in',

       'utf8': '✓',

       '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)

首先构造一个表单,复制各个字段,其中 email 和 password 是以变量的形式传递。然后再用 Session 对象的 post() 方法模拟登录即可。由于 requests 自动处理了重定向信息,我们登录成功后就可以直接跳转到首页,首页会显示所关注人的动态信息,得到响应之后我们用 dynamics() 方法来对其进行处理。接下来再用 Session 对象请求个人详情页,然后用 profile() 方法来处理个人详情页信息。

其中,dynamics() 方法和 profile() 方法的实现如下所示:

def dynamics(self, html):

   selector = etree.HTML(html)

   dynamics = selector.xpath('//div[contains(@class, "news")]//div[contains(@class, "alert")]')

   for item in dynamics:

       dynamic = ' '.join(item.xpath('.//div[@class="title"]//text()')).strip()

       print(dynamic)


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)

在这里,我们仍然使用 XPath 对信息进行提取。在 dynamics() 方法里,我们提取了所有的动态信息,然后将其遍历输出。在 prifile() 方法里,我们提取了个人的昵称和绑定的邮箱,然后将其输出。

这样,整个类的编写就完成了。

5. 运行

我们新建一个 Login 对象,然后运行程序,如下所示:

if __name__ == "__main__":

   login = Login()

   login.login(email='cqc@cuiqingcai.com', password='password')


在 login() 方法传入用户名和密码,实现模拟登录。

可以看到控制台有类似如下输出:

GrahamCampbell  starred  nunomaduro/zero-framework

GrahamCampbell  starred  nunomaduro/laravel-zero

happyAnger6  created repository  happyAnger6/nodejs_chatroom

viosey  starred  nitely/Spirit

lbgws2  starred  Germey/TaobaoMM

EasyChris  starred  ageitgey/face_recognition

callmewhy  starred  macmade/GitHubUpdates

sindresorhus  starred  sholladay/squatter

SamyPesse  starred  graphcool/chromeless

wbotelhos  starred  tkadlec/grunt-perfbudget

wbotelhos  created repository  wbotelhos/eggy

leohxj  starred  MacGesture/MacGesture

GrahamCampbell  starred  GrahamCampbell/Analyzer

EasyChris  starred  golang/go

mitulgolakiya  starred  veltman/flubber

liaoyuming  pushed to  student  at  Germey/SecurityCourse

leohxj  starred  jasonslyvia/a-cartoon-intro-to-redux-cn

ruanyf  starred  ericchiang/pup

ruanyf  starred  bpesquet/thejsway

louwailou  forked  Germey/ScrapyTutorial  to  louwailou/ScrapyTutorial

Lving  forked  shadowsocksr-backup/shadowsocksr  to  Lving/shadowsocksr

qifuren1985  starred  Germey/ADSLProxyPool

QWp6t  starred  laravel/framework

Germey ['1016903103@qq.com', 'cqc@cuiqingcai.com']

可以发现,我们成功获取到关注的人的动态信息和个人的昵称及绑定邮箱。模拟登录成功!

6. 结语

我们利用 requests 的 Session 实现了模拟登录操作,其中最重要的还是分析思路,只要各个参数都成功获取,那么模拟登录是没有问题的。

登录成功,这就相当于建立了一个 Session 会话,Session 对象维护着 Cookies 的信息,直接请求就会得到模拟登录成功后的页面。

最后,如果本文对您有帮助,可以给我点一个赞支持一下!

同时,如果你喜欢本系列爬虫文章,可以点个关注跟着我一起学习更多爬虫知识。

相关文章
|
6天前
|
数据采集 存储 XML
Python爬虫定义入门知识
Python爬虫是用于自动化抓取互联网数据的程序。其基本概念包括爬虫、请求、响应和解析。常用库有Requests、BeautifulSoup、Scrapy和Selenium。工作流程包括发送请求、接收响应、解析数据和存储数据。注意事项包括遵守Robots协议、避免过度请求、处理异常和确保数据合法性。Python爬虫强大而灵活,但使用时需遵守法律法规。
|
7天前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
8天前
|
数据采集 Web App开发 监控
高效爬取B站评论:Python爬虫的最佳实践
高效爬取B站评论:Python爬虫的最佳实践
|
9天前
|
数据采集 存储 JSON
Python爬虫开发中的分析与方案制定
Python爬虫开发中的分析与方案制定
|
13天前
|
数据采集 Web App开发 JavaScript
爬虫策略规避:Python爬虫的浏览器自动化
爬虫策略规避:Python爬虫的浏览器自动化
|
13天前
|
数据采集 存储 XML
Python实现网络爬虫自动化:从基础到实践
本文将介绍如何使用Python编写网络爬虫,从最基础的请求与解析,到自动化爬取并处理复杂数据。我们将通过实例展示如何抓取网页内容、解析数据、处理图片文件等常用爬虫任务。
|
13天前
|
测试技术 API 数据安全/隐私保护
Python连接到Jira实例、登录、查询、修改和创建bug
通过使用Python和Jira的REST API,可以方便地连接到Jira实例并进行各种操作,包括查询、修改和创建Bug。`jira`库提供了简洁的接口,使得这些操作变得简单易行。无论是自动化测试还是开发工作流的集成,这些方法都可以极大地提高效率和准确性。希望通过本文的介绍,您能够更好地理解和应用这些技术。
54 0
|
15天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
59 6
|
3月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
175 4
|
3月前
|
数据采集 存储 搜索推荐
打造个性化网页爬虫:从零开始的Python教程
【8月更文挑战第31天】在数字信息的海洋中,网页爬虫是一艘能够自动搜集网络数据的神奇船只。本文将引导你启航,用Python语言建造属于你自己的网页爬虫。我们将一起探索如何从无到有,一步步构建一个能够抓取、解析并存储网页数据的基础爬虫。文章不仅分享代码,更带你理解背后的逻辑,让你能在遇到问题时自行找到解决方案。无论你是编程新手还是有一定基础的开发者,这篇文章都会为你打开一扇通往数据世界的新窗。