python爬虫2:requests库-原理

python爬虫2:requests库-原理

前言

​ python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。

目录结构

文章目录

    • python爬虫2:requests库-原理
      • 1. 概述
      • 2. response对象
        • 2.1 encoding属性
        • 2.2 url属性
        • 2.3 status_code属性
        • 2.4 cookies属性
        • 2.5 request.headers属性
        • 2.6 headers属性
        • 2.7 text属性
        • 2.8 content属性
      • 3. GET请求
        • 3.1 方法概述
        • 3.2 常用参数
        • 3.2 参数的用法举例
      • 4. POST请求
      • 5. 代理设置
      • 6. 会话维持
      • 7. ssl证书
      • 8. 总结

1. 概述

​ python其实自带一个请求库,即urllib,不过这个库并不是很好使,因此大部人都还是采用的第三方库requests。

​ Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。

​ 在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化,使用Requests可以轻而易举的完成浏览器可有的任何操作。

​ 另外,requests的安装十分简单,仅需要pip一下即可:

pip install requests

​ 如果网不好,还可以指定镜像源,下载更快:

pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

​ 可以使用以下代码检验是否安装成功:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.content.decode('utf-8'))

​ 返回结果如下:

在这里插入图片描述

2. response对象

​ 当我们使用get、post或者其他方式去请求的时候,我们就会得到一个response对象(比如上面测试代码中get函数返回的对象),你可以称呼它为响应对象,下面我们来学习这个对象的常用属性和方法。

2.1 encoding属性

​ 作用: 返回网页的编码格式。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.encoding)

​ 打印结果为:

ISO-8859-1

​ 这个结果也是编码的一种,不过是我们国内的标准,其他常见的有utf-8之类的。

2.2 url属性

​ 作用: 返回响应服务器的url。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.url)

​ 打印结果为:

https://www.baidu.com/

不要小瞧这个属性。有时候我们访问的是:http://www.test.com,但是由于这个网站有重定向,因此我们实际访问的是: http://www.good.com ,这样我们通过这个属性确定我们真实访问的网址。

2.3 status_code属性

​ 作用: 返回响应的状态码。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.status_code)

​ 打印结果为:

200

什么是状态码?

​ 简单来说就是你访问的这个网站状态怎么样,是正常访问,还是说服务器错误,还是网络有问题等等。

​ 这里介绍一下常见的相应状态码:

2xx | 正常
3xx | 重定向
4xx | 错误
5xx | 服务器错误

2.4 cookies属性

​ 作用: 返回cookie对象。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.cookies)

​ 打印结果:

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

什么是cookie?

​ 这里简单说明一下什么是cookie,可以简单理解为一个存在我们电脑本地的临时身份文件,比如你访问一个网站,你首次登录了它,然后你把这个网站关掉,再次打开,发现不需要重新登录,这就是cookie发挥了作用,当你登陆后,在本地创建了一个临时文件用于后期登录。

2.5 request.headers属性

​ 作用: 返回请求头。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.request.headers)

​ 打印的值为:

{'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

什么是请求头?

​ 简单来说,你访问一个网站,比如百度搜索,你肯定会搜索某个东西,那么自然你请求这个网站,发送给这个网站的信息中带有这个东西,我们一般称之为请求头,其包含了你所请求的所有信息。

​ 从上面的返回值可以看出一点:百度网站知道你是python脚本,从'User-Agent': 'python-requests/2.31.0'就可以看出。因此,我们写爬虫的时候必须要做一定的伪装,不然直接就被识别出来是爬虫了

2.6 headers属性

​ 作用: 返回响应头。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.headers)

​ 打印结果:

{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Fri, 04 Aug 2023 05:36:28 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:23:55 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}

什么是响应头?

​ 响应头就是服务器/网站自身返回给我们的部分信息、

2.7 text属性

​ 作用: 返回网页的源码,但是是按照chardet模块推测出的编码进行解码的结果(不准确)。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.text)

​ 返回结果:

<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>ç™¾åº¦ä¸€ä¸‹ï¼Œä½ å°±çŸ¥é“</title></head> <body link=#0000cc> <div id=wrapper> 
....

# 部分结果

​ 说明:text返回的是网页源码,但是解码时是推测的,有时候并不准确。因此,我们更加常用content属性,加上自己解码,更加准确。

2.8 content属性

​ 作用: 返回网页源代码的bytes形式的结果。

​ 代码:

import requests
# 网址
url = 'https://www.baidu.com'
# 请求
response = requests.get(url)
# 打印返回结果
print(response.content.decode('utf-8'))

​ 打印的部分结果:

<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> 
....

# 部分结果

如何判断网页编码形式?

​ 这个简单,随便打开一个网页,比如百度,点击鼠标右键,查看源码,找到下图中的内容(html网页源码整体框架是固定的,因此你在任何网页上都可以找到类似的内容):

在这里插入图片描述

3. GET请求

3.1 方法概述

​ get请求是平时我们最常用的请求方式之一。在requests模块中,提供给我们了非常方便的get请求方式:

import requests
url = 'http://www.baidu.com'
response = requests.get(url)
print(response.status_code)

3.2 常用参数

参数作用
url请求的地址
headers请求头参数(字典)
params请求的参数(字典)
cookies请求的cookies参数(字典)
timeout超时时间设置

3.2 参数的用法举例

​ 这里举一个简单的例子,来说明一下这些参数怎么用。

​ 之前不是说了嘛,直接用脚本去访问百度网站,会被识别出是python脚本,因此我们可以利用请求头参数进行简单的伪装:

import requests
# 地址
url = 'https://www.baidu.com'
# 伪造请求头
headers = {
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
}
# 访问
response = requests.get(url,headers=headers)
# 打印
print(response.request.headers)

​ 注意:传入的参数必须为字典形式,内容必须符合请求头的内容

​ 打印的结果如下:

{'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

​ 可以看出,确实伪造成功了。

如何正确书写请求头格式?

​ 这一点很重要也很简单,你随便打开一个网页,鼠标右键,选择”检查“(Google浏览器为例),然后按下图操作,即可看见请求头内容:

在这里插入图片描述

​ 这里我介绍一下最常见的请求头参数内容:

User-Agent : 客户端浏览器的版本信息
Host : 服务器的主机
Referer:表示从哪个页面跳转到当前的页面
Cookie:用于记录客户端的身份信息,例如通过cookie登录网站
x-forward-for:表示客户端的IP地址,一般被称为”XXF“头,服务器通过这个字段可以知道客户端的真实IP或代理IP

​ (params参数后面单独出一个案例讲解)

4. POST请求

​ post请求也是我们网站中最常用的请求方式之一,一般提交表单几乎都是post请求。而,在requests模块中,post请求与get请求的使用方法上差别在于参数(params变为了data,headers参数和其他参数是相同的):

data: 接收一个字典,里面爬虫发出的数据

5. 代理设置

​ 使用代理,可以减少我们自己真实IP暴漏的概率。

​ 简单来说,代理就是使用别人IP来访问网站,这样网站如果进行检测,只能检测到别人的IP地址,根本不知道其实是你在访问他的网站。

​ 一般代理IP按照匿名程度分为:

  • 高匿:
    • 别人不知道你的真实IP
  • 透明:
    • 别人知道你的真实IP

​ 而,在requests库中,get、post请求方法中都有一个参数 proxies ,这个参数就是设置代理使用的。

​ 使用方法如下:

import requests

proxies = {
    'http/https':'http/https:ip:port',
    'http/https':'http/https:ip:port',
    'http/https':'http/https:ip:port',
    'http/https':'http/https:ip:port'
}
requests.get(url,proxies=proxies)

​ 当我们需要追求效率时,除了可以采用多任务的方式,还有一个方式就是使用代理。比如我们需要下载图片,为了不被网站检测出我们是爬虫,我们不得不牺牲效率,比如说每爬取一张图片就休息一秒钟,这样的效率显然很低。但是一旦我们一秒钟爬取个几百张图片,非常容易被网站检测出这个用户不是一个人,因为真正的人不可能一秒钟下载几百张图片,于是网站便会短时间封禁我们的ip,导致我们无法继续访问,以至于爬虫失效。

​ 这时我们需要代理,这样我们就可以在爬取的时候使用不同的ip地址了。

​ 那么总结一下,为什么需要代理呢?

  • 减少自己真实IP暴漏的概率
  • 可以使用多个代理IP来实现快速访问
因为,现在的网站几乎都会屏蔽速度过快的访问,比如一秒几十次乃至几百、上千万次的访问,这样的访问一看就不正常,因此站长几乎都会屏蔽乃至禁止你的IP,因此我们可以使用多个代理IP,比如我们使用100个,那么我们每秒就会访问100次都不会有任何的问题

6. 会话维持

​ 我们有时候遇见一些网站会强制你登录才能去获取数据。此时你知道想要登录网站需要去使用post方式请求,但是当你请求成功后再用get方式去访问网站,你会发现你被拒绝了,这意味着你的get请求是一个新的请求,而不是在post请求成功后以post为基础的请求。如果你无法理解上面的话,你可以这样理解,一个get就是打开一个浏览器,两个浏览器之间是无法通信的,所以你第二次请求相当于打开一个新的浏览器,自然无法获取内容。

​ 因此,我们需要一些方法来搞定这个问题。

​ 参考代码如下:

#下面给出的是思路,不是具体的代码,具体的代码还是根据实际案例来讲
import requests

#创建session对象
session = requests.session()
#使用session对象去发送post请求
session.post(.....)     #这里post的用法和requests.post()用法一致
#请求成功后再用session对象去请求只有登录才能访问的页面
response = session.get(....)   #这里post的用法和requests.get()用法一致
#接下来再去操作即可

​ (这个也会单独出一篇讲解案例)

7. ssl证书

​ 有时候,我们的爬虫需要忽略ssl证书,即我们手动访问的时候会显示这个网页不安全/ssl证书过期等提示。

​ 忽略的方法很简单,参考如下:

import requests

response = requests.get('https://www.baidu.com',verify=False)
print(response.status_code)

8. 总结

​ 本篇文章主要梳理了requests常用方法,接下来的文章会对本文中涉及的一些方法进行举例说明。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/65568.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记-JVM-对象结构及生命周期

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 对象的创建流程 常量池检查:检查new指令是否能在常…

【设计模式——学习笔记】23种设计模式——中介者模式Observer(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入案例一普通实现中介者模式 案例二 介绍基础介绍登场角色尚硅谷 《图解设计模式》 案例实现案例一&#xff1a;智能家庭类图实现 案例二&#xff1a;登录页面逻辑实现说明类图实现 总结文章说明 案例引入 案例一 普通实现 在租房过程中&#xff0c;客户可能…

2.5D游戏是如何做出来的呢,2.5D游戏快速制作教程

前言 【Unity实战篇 】 | 如何制作一款2.5D游戏&#xff0c;2.5D游戏制作案例一、2.5D 游戏概念二、绘制地图三、添加玩家动画和移动等操作四、视角配置4.1 调整摄像机与场景对象的角度4.2 增加镜头旋转功能 五、游戏效果展示 总结 前言 玩过游戏的朋友都知道&#xff0c;市面…

HarmonyOS NEXT,生命之树初长成

在不同的神话体系中&#xff0c;都有着关于生命之树的记载。 比如在北欧神话中&#xff0c;一株巨大的树木联结着九大世界&#xff0c;其被称为“尤克特拉希尔”Yggdrasill。在中国的《山海经》中&#xff0c;也有着“建木”的传说&#xff0c;它“有九欘&#xff0c;下有九枸&…

idea添加翻译插件并配置有道翻译

1、安装Translation插件 2、 创建有道云应用 有道智云控制台 3、设置idea 4、效果&#xff08;选中文本右键翻译&#xff0c;默认快捷键CtrlShiftY&#xff09;

安达发制造工业迈向智能化:APS高级计划排程助力提升生产效率

随着市场竞争的加剧&#xff0c;制造企业纷纷寻求提高生产效率和降低成本的方法。近年来&#xff0c;越来越多的制造企业开始采用APS(高级计划与排程)系统&#xff0c;以优化生产计划和排程&#xff0c;提高生产效率&#xff0c;并在竞争中取得优势。 现代制造业通常面临复杂的…

Idea中maven无法下载源码

今天在解决问题的时候想要下载源码&#xff0c;突然发现idea无法下载&#xff0c;这是真的蛋疼&#xff0c;没办法查看原因&#xff0c;最后发现问题的原因居然是因为Maven&#xff0c;由于我使用的idea的内置的Bundle3的Maven&#xff0c;之前没有研究过本地安装和内置的区别&…

ESP 32 蓝牙虚拟键盘链接笔记本电脑的键值问题

由于打算利用esp32 通过蓝牙链接电脑后实现一些特俗的键盘功能&#xff0c;所以就折腾了一下&#xff0c;折腾最耗费时间的却是键值问题&#xff0c;让一个20多年的老司机重新补充了知识 过程曲折就不说了&#xff0c;直接说结果。 我们通过网络搜索获取的键值和蓝牙模拟键盘传…

Leetcode-每日一题【剑指 Offer 11. 旋转数组的最小数字】

题目 把一个数组最开始的若干个元素搬到数组的末尾&#xff0c;我们称之为数组的旋转。 给你一个可能存在 重复 元素值的数组 numbers &#xff0c;它原来是一个升序排列的数组&#xff0c;并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如&#xff0c;数组 [3,4…

【论文阅读】对抗溯源图主机入侵检测系统的模仿攻击(NDSS-2023)

作者&#xff1a;伊利诺伊大学芝加哥分校-Akul Goyal、Gang Wang、Adam Bates&#xff1b;维克森林大学-Xueyuan Han、 引用&#xff1a;Goyal A, Han X, Wang G, et al. Sometimes, You Aren’t What You Do: Mimicry Attacks against Provenance Graph Host Intrusion Detect…

docker容器监控:Cadvisor +Prometheus+Grafana的安装部署

目录 Cadvisor PrometheusGrafana的安装部署 一、安装docker&#xff1a; 1、安装docker-ce 2、阿里云镜像加速器 3、下载组件镜像 4、创建自定义网络 二、部署Cadvisor 1、被监控主机上部署Cadvisor容器 2、访问cAdvisor页面 三、安装prometheus 1、部署Prometheus…

20230806将ASF格式的视频转换为MP4

20230806将ASF格式的视频转换为MP4 2023/8/6 18:47 缘起&#xff0c;自考中山大学的《计算机网络》&#xff0c;考试《数据库系统原理》的时候找到视频&#xff0c;由于个人的原因&#xff0c;使用字幕更加有学习效率&#xff01; 由于【重型】的PR2023占用资源较多&#xff0c…

Spring security之JWT

JWT 这里写目录标题 JWT一级目录二级目录三级目录1.什么是JWT 2.JWT的组成部分3.编码/解码4.特点5. 为什么使用JWT5.1传统的验证方式 5.2基于JWT的验证方式6.JWT进行登录验证6.1依赖安装6.2编写UserDetailServiceImpl类6.3编写UserDetailsImpl类6.4 实现config.SecurityConfig类…

算法与数据结构(二十二)动态规划解题套路框架

动态规划解题套路框架 此文只在个人总结 labuladong 动态规划框架&#xff0c;仅限于学习交流&#xff0c;版权归原作者所有&#xff1b; 动态规划问题&#xff08;Dynamic Programming&#xff09;应该是很多读者头疼的&#xff0c;不过这类问题也是最具有技巧性&#xff0c…

替换开源LDAP,某科技企业用宁盾目录统一身份,为业务敏捷提供支撑

客户介绍 某高科技企业成立于2015年&#xff0c;是一家深耕于大物流领域的人工智能公司&#xff0c;迄今为止已为全球16个国家和地区&#xff0c;120余家客户打造智能化升级体验&#xff0c;场景覆盖海陆空铁、工厂等货运物流领域。 该公司使用开源LDAP面临的挑战 挑战1 开源…

【用于全变分去噪的分裂布雷格曼方法】实施拆分布雷格曼方法进行总变异去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

docker菜谱

DockerHub&#xff1a;https://hub.docker.com/ 记录docker常用软件安装&#xff0c;欢迎大家来投稿。&#x1f60e;&#x1f60e;&#x1f60e; 文章目录 1. Redis2. MariaDB 1. Redis dockerhub:https://hub.docker.com/_/redis 1、下载redis镜像&#xff1a; docker pull r…

【MFC】05.MFC第一大机制:程序启动机制-笔记

MFC程序开发所谓是非常简单&#xff0c;但是对于我们逆向人员来说&#xff0c;如果想要逆向MFC程序&#xff0c;那么我们就必须了解它背后的机制&#xff0c;这样我们才能够清晰地逆向出MFC程序&#xff0c;今天这篇文章就来带领大家了解MFC的第一大机制&#xff1a;程序启动机…

echarts 图表饼状图 实例

效果图&#xff1a; 代码&#xff1a; draw(data1, data2) {var option {// backgroundColor: rgb(10,36,68),color: [#F19611 ,#0095FE,#162D86,#0096FF,#05F8FF,#FFD985,#FACDAA,#F4A49E,#EE7B91,#E85285,#BE408C,#942D93,#171E6D,#1E3388,#27539B,#3073AE,#3993C2,#42B3D…

JVM如何调优

一、JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范&#xff0c;JVM将内存划分为&#xff1a; New&#xff08;年轻代&#xff09; Tenured&#xff08;年老代&#xff09; 永久代&#xff08;Perm&#xff09; 其中New和Tenured属于堆内存&#xff0c;堆内存会从JVM启动参…