爬虫入门教程⑦— jupyter与requests的初步使用

jupyter 是一个简易的,方便的写Python代码的工具包,requests是Python里非常好用的用来发送 http 请求的包。

开始学习本教程之前,请确保你已经安装了Python,并且安装了Python包 jupyterrequests 了。如果没有,那请参照以下教程进行安装:


1. jupyter的简单使用

老规矩:Windows键+X键选择 命令提示符
打开了命令提示符,那么我们输入命令: jupyter notebook 回车。
接着你的浏览器会自动打开下面的界面:
注:
如果没有自动打开浏览器却显示了一个网址在窗口里面,那么是你电脑没有设置默认浏览器或者默认浏览器设置错误导致的;
如果浏览器打开了网页却不显示任何东西,无法正常使用,请检查你的浏览器的版本是否比较陈旧,推荐使用Firefox、Chrome、QQ浏览器等使用非IE内核或高等级IE内核的浏览器。

jupyter notebook界面

接着我们点击网页右边的 new,选择 Python3。(我的jupyter多了个Python2的选项,那是因为我自己给jupyter配置了Python2,默认情况下,只有你当前的Python版本的文件选项。)

创建Python文件

选择了创建文件之后,浏览器打开了一个新的界面,这就是我们的代码编辑界面啦,从此以后就可以开开心心写代码了。
我们在下面的In [ ]:那里输入我们的第一个程序的第一条语句:
print("Hello World")
然后点击画面上方的Run按钮,就运行我们的程序啦。效果如图:

输出Hello World


Requests: HTTP for Humans

这是 requests 的 slogan。非常简单明了,我觉得翻译成中文大概是:给人使用的 HTPP 请求库
根据我个人经验来说,看到过很多初学者(也包括曾经的我),都跟着网上很老的爬虫教程,使用urlliburllib2来发起请求。这样的结果是什么?不仅写代码效率非常低下,而且代码量比requests多得多,同时代码也难以理解。
这几个过时的库一点也不友好,简直不像是给人使用的。
所以从遇到requests的第一天起,我就永远地抛弃了urllib之类的库了。

requests的作者,是一位非常帅气的摄影师小哥。目前requests在GitHub上已经获得了32062个Star

下面我们来学习requests的基本使用。

 

2. import requests并发起一个请求

我们在jupyter的新的一个输入里面,键入下面的代码并点击运行:

import requests  
print(requests.get("https://www.baidu.com"))  

注意:括号都是英文的括号哦
运行结果:

输出get请求

import requests: 代码文件里面引入requests这个包以便后面代码的使用
print(requests.get("https://www.baidu.com")):用requests向百度首页发起一个get请求,并打印出请求的结果(response对象)。
这就已经完成了我们使用浏览器打开百度首页的过程了。那为什么我们没看到网页也没看到html呢?我们把代码改成这样再运行一次:

import requests
response = requests.get("https://www.baidu.com")
print(response.status_code)
print(response.content)

运行结果:

输出请求结果

第一行的200,是我们这个请求的HTTP状态码,200表示请求成功,关于状态码前面已经讲解过了:爬虫入门教程③— 必备知识基础(二)HTTP请求简介

第二行开始就是输出的我们获取到的百度首页的HTML代码的二进制字符串b'xxxxx'表示这个字符串是二进制的。
那我们怎么把二进制结果改成我们看得懂的中文结果呢?我们只需要对响应的content(二进制)进行一次解码,常见的解码方式有gbkutf-8
Windows文件用的是gbk编码,有一些比较古老的网页也是用的gbk编码。现在大部分的网页都是用的 utf-8 的编码了。
我们怎么知道网页用的哪个编码呢?一般是看meta信息里面charset的值:

找编码

当然也可以猜,不报错,不乱码,那就对了。

于是我们在输出二进制响应后面加上.decode('utf-8'),把二进制字符转换成字符串:

import requests
response = requests.get("https://www.baidu.com")
print(response.status_code)
print(response.content.decode('utf-8'))

输出如下:


中文编码结果

现在就能看懂了,我们成功打开了百度的首页!
是的,requests发起一个请求就是这么简单。

要发起 post 请求,也同样简单

import requests
form = {'username': 'admin','password': 'admin123456'}
response = requests.post("https://www.baidu.com", data=form)
print(response.content.decode('utf-8'))

这就向百度首页,发起了一个post请求,并且带上了两个参数,参数名是username和password,值是admin和admin123456。post请求我们一般用于对网页发送数据,比如登录,发送图片、文件等等。如果请求方式弄错了,很可能得不到正确的响应的哦

 

3. requests.session的使用

这里要介绍一下cookie:

Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。

cookie就相当于一个令牌,你拿着它去访问网站,网站就能辨别你是谁了。所以如果你登录了,你去访问其他需要登录的网页,都可以直接访问,因为浏览器在你访问的时候,默认会带上cookie。cookie的添加、删除、更新是在服务器返回的响应里获取到的。

requests.get() 是发送请求常用的一个办法。它不能做到的是对cookie的持久化: 上一个请求获取到的cookie,没办法简单地传递到下一个请求去,这样两个requests.get()请求之间没有办法产生联系。如果是对于需要登录的网站来说,这是毁灭性的,我们会一直卡在登录界面。
下面要引入的就是requests的session。它能够自动管理cookie,也能够进行cookie的持久化。用法也很简单:

import requests
http_session = requests.session()
response = http_session.get("https://www.baidu.com")
print(response.content.decode('utf-8'))

我们定义了一个http_session用来作为我们的session。然后我们使用这个http_seesion发出的每个请求,都会自动带上cookie,也会自动处理网站服务器返回的对cookie的操作。
这些过程对我们不可见,而我们只需要使用就好了!简直完美!

 

4. 把从浏览器获取到的cookie添加到session里来绕过登录

注:此小节为进阶教程,不理解可暂时跳过。

首先补充一下cookie的知识:

  • 原因:http请求是无状态的,也就是说,你的每一次请求,网站服务器都会认识是一次新的请求。

  • 问题:既然每一次请求都是新的请求,那么网站识别用户就遇到困难了:一个网站需要服务于多个用户,每个用户的需要呈现的内容可能是不同的。如果每次请求都是全新的,服务器会不知道是谁发过来的,进而就可能造成一个混乱的局面,把A的消息发给了B,C的邮件给了A等等。

  • 解决方案:服务器如果需要识别你的身份,那它就给你发送一个或多个cookie(如果不需要对你进行特异性识别,那就没必要设置cookie了),之后你的每个请求默认会带上服务器设置的cookie(浏览器自动处理)。由于服务器给每个用户的分配的cookie的值是不同的,那服务器就可以轻松地通过cookie的值来识别用户了。

  • 拓展:既然服务器是通过cookie这个令牌识别你是谁的,那么只要你的请求带上了任意一个人的cookie去访问服务器,那么服务器就会认为你就是那个人。所以在以前有中间人攻击这个事情,黑客就是通过拦截你的请求,找到你的cookie,自己伪装成你,然后帮他发广告或者是进行一些其他的危险操作以获得利润。

如果我们需要爬取一个需要登录的网站,但是他的登录流程非常麻烦,甚至需要输入验证码。我们有没有什么比较轻便的办法来解决这个问题呢?
当然有:我们在浏览器上登录了,然后把浏览器上的网站发送给你的cookie,按照格式添加到我们的session里面,那么我们就无需登录,成功伪装成了浏览器里面的自己的账号了,进而可以直接进行爬取了(每个请求带上cookie,服务器就会认为我们是已经登录过了)。

怎么获取浏览器的cookie呢?
F12打开调试模式,然后选中NetWork(网络)。接着鼠标点到网页上去,按F5刷新界面。我们马上可以看到在调试窗口里面的列表有一个接一个的请求出现了,我们找到第一个请求(通常是第一个,具体请看请求的网址),点击一下,就显示出了这个请求的具体信息了。
接着再找到Request Header里面的Cookie

找到cookie

在我的截图里面,百度给我发送了非常多的cookie,你可能没这么多,但是也不影响,毕竟这只是个示例。

  • 接着我们把所有的cookie复制下来。
  • 每一条cookie是以;隔开的,所以我们先以;把这些cookies分开,分割为一条条的cookie。
  • 对于每条cookie我们再以第一个=把一条cookie分为 name 和 value 两个部分。
  • 然后我们把这些key-value的数据,添加到一个dict里面
  • 最后把cookie添加到 http_session 的cookies里面。

举个例子,复制下来的cookies字符串为
"sessionid=124586245;name=pikaqiu;FDS=fdsa=okok;how=areyou"
首先我们以;切割这个字符串得到了下面这几条cookie

"sessionid=124586245"
"name=pikaqiu"
"FDS=fdsa=okok"
"how=areyou"

然后我们再把这几条cookie转换成requests能够接受的格式:

cookies = {
           'sessionid': '124586245',
           "name": "pikaqiu",
            "FDS": "fdsa=okok",
            "how": "areyou",
          }

最后再把这个cookie添加到requests提供的http_session里面,之后这个session就会自动为我们处理cookie了,包括每个请求发送cookie,修改和删除cookie的信息。

下面以上图的百度举个例子,下面就是采用了我自己的cookie访问百度的例子:

import requests
http_session = requests.session()
cookies = {'BAIDUID': 'CC97B75E17BC78:FG=1',
            'BIDUPSID': 'CC97B75E17FE0BEEBC78',
            'PSTM': '15700',
            'BDSFRCVID': 'th-sJeC626F0ZTQA',
            'H_BDCLCKID_SF': 'tJPjVC0yt',
            'ispeed_lsm': '2',
            'H_PS_645EC': '00e6qFET6oh4QC9Q',
           }  # 为了减少篇幅,我删掉了后面的几个cookie,你们可不能偷懒哦~
requests.utils.add_dict_to_cookiejar(http_session.cookies, cookies)
response = http_session.get("https://www.baidu.com")
print(response.content.decode('utf-8'))

通过把浏览器的cookie添加到程序里面,然后用程序来进行访问,我们就可以节约用程序登录的步骤,专心进行我们其他的操作了。这个办法同样适用于一些不需要登录,但是对cookie有要求的网站。

本节到此结束,下一节会是关于如何从HTML字符串里面提取出我们需要的内容的教程。感谢观看。


传送门:

下一章:

所有的章节:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Se...
    chinariver阅读 5,588评论 1 49
  • 在爬虫入门系列(一):快速理解HTTP协议中介绍了 HTTP 协议,Python 提供了很多模块来基于 HTTP ...
    liuzhijun阅读 456评论 0 9
  • 1. 概述 本文主要介绍网络爬虫,采用的实现语言为Python,目的在于阐述网络爬虫的原理和实现,并且对目前常见的...
    Lemon_Home阅读 2,723评论 0 21
  • 会当凌绝顶,一览众山小。这是我高中的语文老师带我们游玩时,在课堂上常念的一句。很多时候,无论是登山望远亦或有什么心...
    大巫见小巫panda阅读 234评论 0 0
  • 文/疯自在 挥袂清风,腹中文武,应许吾者。 落笔从容,才华半点,掩白衣高雅。 摊开韵底,吟宽未敢,拈赋自当潇洒。 ...
    小疯子自在阅读 351评论 5 32