当前位置: 首页 > article >正文

【Python深入浅出㊵】解锁Python3的requests模块:网络请求的魔法钥匙

目录

  • 一、requests 模块初相识
  • 二、requests 模块的基本使用
    • (一)安装 requests 模块
    • (二)发送 GET 请求
    • (三)发送 POST 请求
    • (四)响应内容处理
  • 三、requests 模块的高级应用
    • (一)会话维持(session)
    • (二)证书验证
    • (三)设置代理
  • 四、实战案例
    • (一)简单网页爬虫
    • (二)模拟登录网站
  • 五、总结与展望


一、requests 模块初相识

在 Python 的网络编程领域中,requests模块就如同一位得力助手,为开发者们在网络数据交互的世界里披荆斩棘。它的存在,极大地简化了 HTTP 请求的发送与处理过程,让原本复杂繁琐的网络操作变得轻松易懂。

与 Python 标准库中的urllib、urllib3等网络请求库相比,requests模块有着诸多令人瞩目的优势。首先,它的 API 设计简洁明了,极为人性化,即便是刚接触 Python 网络编程的新手,也能迅速上手。以发送 GET 请求为例,在urllib库中,你可能需要这样编写代码:

import urllib.request

url = 'https://www.example.com'
req = urllib.request.Request(url)
with urllib.request.urlopen(req) as response:
    data = response.read().decode('utf-8')
    print(data)

而使用requests模块,只需简单的两行代码:

import requests

response = requests.get('https://www.example.com')
print(response.text)

如此对比,高下立判,requests模块的代码简洁性不言而喻。

其次,requests模块在功能的丰富性与全面性上表现出色。它不仅对各种 HTTP 请求方法,如 GET、POST、PUT、DELETE、HEAD、OPTIONS 等提供了原生支持,还能轻松处理请求参数、请求头、Cookies、文件上传等复杂操作。在处理 POST 请求时,若要传递表单数据,requests模块只需将数据以字典形式传递给data参数即可,如下所示:

import requests

url = 'https://www.example.com/login'
data = {'username': 'user', 'password': 'pass'}
response = requests.post(url, data=data)
print(response.text)

反观urllib库,处理此类操作则需要更多的步骤和代码量。

另外,requests模块还具备出色的可扩展性。通过插件和适配器,它能够满足各种特定场景下的需求,例如在处理代理服务器、自定义认证机制等方面,都展现出了强大的灵活性。

从社区支持的角度来看,requests模块拥有庞大且活跃的社区。在遇到问题时,开发者可以轻松地在社区中找到丰富的文档、教程、示例代码以及其他开发者的经验分享,这无疑为解决问题提供了极大的便利,也加快了开发的速度。

二、requests 模块的基本使用

(一)安装 requests 模块

在开始使用requests模块之前,首先需要确保它已经被安装到你的 Python 环境中。安装requests模块的方法多种多样,下面为你详细介绍在不同环境下的安装方式。

  1. 命令行安装
    如果你使用的是 Python 3.4 及以上版本,pip已经默认集成在 Python 环境中。打开命令行终端,输入以下命令即可完成安装:
pip install requests

在安装过程中,pip会自动从 Python Package Index(PyPI)上下载requests模块及其依赖项,并将它们安装到你的 Python 环境中。

若你的pip版本较低,可能会遇到一些问题,此时可以先更新pip:

python -m pip install --upgrade pip

更新完成后,再执行安装requests的命令。

  1. PyCharm 中安装
    1. 打开 PyCharm,点击菜单栏中的 “File”,选择 “Settings”。
    1. 在弹出的设置窗口中,找到 “Project: [你的项目名称]”,点击展开后选择 “Python Interpreter”。
    1. 在 Python Interpreter 界面中,点击右上角的 “+” 按钮,这将打开 Python 包的搜索界面。
    1. 在搜索框中输入 “requests”,然后在搜索结果中找到 “requests” 包,点击 “Install Package” 按钮。
    1. PyCharm 会自动下载并安装requests模块,安装完成后,你就可以在项目中使用它了。

(二)发送 GET 请求

  1. 简单 GET 请求示例
    GET 请求是 HTTP 协议中最常用的请求方法之一,主要用于从服务器获取资源。下面以获取百度首页为例,展示如何使用requests.get()方法发送简单的 GET 请求:
import requests

url = 'https://www.baidu.com'
response = requests.get(url)
print(response.text)

在上述代码中:

  • 首先导入requests模块,这是使用requests库的基础。
  • 然后定义了目标 URL,即百度的首页地址https://www.baidu.com。
  • 接着使用requests.get(url)方法发送 GET 请求,requests.get()方法会返回一个响应对象response。
  • 最后通过response.text属性获取响应的文本内容,并将其打印出来。这里的response.text返回的是经过编码解析后的字符串,方便我们直接查看和处理。
  1. 传递参数的 GET 请求
    在实际应用中,我们常常需要在 GET 请求中传递参数,以获取特定的资源。例如,在百度搜索中,我们需要传递搜索关键词。在requests模块中,通过params参数来传递这些数据。以下是一个以百度搜索 “Python 教程” 为例的代码示例:
import requests

url = 'https://www.baidu.com/s'
params = {'wd': 'Python教程'}
response = requests.get(url, params=params)
print(response.url)
print(response.text)

在这段代码中:

  • 定义了百度搜索的 URLhttps://www.baidu.com/s,其中/s表示搜索页面。
  • 创建了一个字典params,其中键wd是百度搜索参数的名称,值Python教程是我们要搜索的关键词。
  • 在调用requests.get()方法时,除了传入 URL,还传入了params=params参数,这会将params字典中的数据以查询字符串的形式拼接到 URL 后面。
  • 通过打印response.url,可以看到实际请求的 URL,它会类似于https://www.baidu.com/s?wd=Python教程,这表明参数已经成功传递。
  • 最后打印response.text,查看搜索结果页面的内容。

(三)发送 POST 请求

  1. 以 form 表单形式提交数据
    POST 请求在 HTTP 协议中主要用于向服务器提交数据,例如用户登录、表单提交等场景。与 GET 请求不同,POST 请求的数据通常不会显示在 URL 中,而是放在请求体中,这使得它更适合处理敏感信息或大量数据。

在requests模块中,将请求参数构造成字典,然后利用requests.post()的data参数以 form 表单形式提交数据。下面是一个模拟用户登录的示例:

import requests

url = 'https://example.com/login'
data = {
    'username': 'your_username',
    'password': 'your_password'
}
response = requests.post(url, data=data)
print(response.text)

在上述代码中:

  • 定义了登录页面的 URLhttps://example.com/login。
  • 创建了一个包含用户名和密码的字典data,模拟表单数据。
  • 使用requests.post()方法发送 POST 请求,将data作为参数传递给data参数,这样数据就会以 form 表单的形式被提交到服务器。
  • 服务器处理请求后返回响应,通过response.text查看响应内容,判断登录是否成功。
  1. 以 json 串提交数据
    在前后端分离的开发模式中,尤其是在与 RESTful API 进行交互时,常常需要以 JSON 串的形式提交数据。这种方式能够更方便地传输结构化数据,并且在数据解析和处理上更加高效。

以下是一个向服务器发送 JSON 数据的示例:

import requests
import json

url = 'https://example.com/api/data'
data = {
    'name': 'John',
    'age': 30,
    'email': 'john@example.com'
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(data), headers=headers)
print(response.text)

在这段代码中:

  • 定义了 API 的 URLhttps://example.com/api/data。
  • 创建了一个包含用户信息的字典data。
  • 为了告知服务器我们发送的数据是 JSON 格式,需要设置请求头headers,其中Content-Type: application/json表示数据类型为 JSON。
  • 使用json.dumps(data)将字典data转换为 JSON 格式的字符串,然后将其作为data参数传递给requests.post()方法。
  • 服务器接收并处理数据后返回响应,通过response.text获取响应内容。

(四)响应内容处理

  1. 获取响应文本
    在发送 HTTP 请求后,我们通常需要获取服务器返回的响应内容。response.text属性用于获取经过编码解析的文本内容,它会根据响应头中的Content-Type字段猜测编码方式,并进行解码。例如:
import requests

response = requests.get('https://www.example.com')
print(response.text)

然而,有时服务器返回的编码信息不准确,或者没有提供编码信息,这可能导致乱码问题。此时,可以手动设置response.encoding属性来指定编码方式。例如,如果已知响应内容是 UTF-8 编码,可以这样处理:

import requests

response = requests.get('https://www.example.com')
response.encoding = 'utf-8'
print(response.text)
  1. 获取二进制响应内容
    当我们需要下载图片、文件等二进制数据时,response.content属性就派上用场了。它返回的是原始的二进制响应内容,以字节串(bytes)的形式表示。以下是一个下载图片的示例:
import requests

url = 'https://example.com/image.jpg'
response = requests.get(url)
with open('image.jpg', 'wb') as f:
    f.write(response.content)

在上述代码中:

  • 使用requests.get(url)获取图片的响应。
  • 以二进制写入模式(‘wb’)打开一个本地文件image.jpg。
  • 通过f.write(response.content)将响应的二进制内容写入文件,从而实现图片的下载。
  • 获取 JSON 格式响应数据
  • 在与 API 进行交互时,很多时候服务器会返回 JSON 格式的数据。requests模块提供了response.json()方法,用于将 JSON 格式的响应数据解析为 Python 字典,方便我们进行后续处理。例如:
import requests

response = requests.get('https://example.com/api/data')
try:
    data = response.json()
    print(data)
except ValueError as e:
    print(f"解析JSON数据失败: {e}")

在这段代码中:

  • 发送 GET 请求获取 API 数据。
  • 使用response.json()尝试将响应数据解析为 Python 字典。
  • 如果解析失败,会抛出ValueError异常,通过try - except语句捕获异常并进行相应处理,提示用户解析失败的原因。
  1. 获取响应状态码
    response.status_code属性用于获取服务器返回的响应状态码,它是一个非常重要的信息,能够帮助我们了解请求的处理结果。常见的状态码及其含义如下:
  • 200:表示请求成功,服务器已成功处理请求并返回了正常的响应。
  • 404:表示请求的资源未找到,通常是因为 URL 错误或资源已被删除。
  • 500:表示服务器内部错误,服务器在处理请求时遇到了问题,无法正常返回响应。

根据不同的状态码,我们可以进行相应的处理。例如:

import requests

response = requests.get('https://example.com')
if response.status_code == 200:
    print("请求成功,获取到数据:")
    print(response.text)
elif response.status_code == 404:
    print("请求的资源未找到,请检查URL是否正确。")
else:
    print(f"请求失败,状态码: {response.status_code}")

在上述代码中,通过判断response.status_code的值,进行不同的处理,从而提高程序的健壮性和用户体验。

三、requests 模块的高级应用

(一)会话维持(session)

  1. session 的概念和作用

在网络通信中,会话维持是指在一系列连续的请求中保持某些状态信息,使得后续请求能够利用之前请求所建立的状态。在 HTTP 协议中,由于其本身是无状态的,即每次请求之间相互独立,服务器无法直接知晓请求之间的关联。然而,在许多实际场景中,如用户登录、购物车操作等,我们需要在多个请求之间保持状态。这就是session发挥作用的地方。

session可以理解为一个会话对象,它能够在多个请求之间保存和传递一些重要的信息,其中最常用的就是cookies。cookies是服务器发送到用户浏览器并保存在本地的一小段数据,它包含了用户的相关信息,如登录状态、用户偏好等。通过session对象,我们可以自动处理这些cookies,使得下一次请求能够带上前一次请求中服务器设置的cookies,从而实现跨请求的状态保持。

以模拟登录为例,当我们使用用户名和密码登录到一个网站时,服务器会验证我们的身份,并返回一个包含登录状态信息的cookie。如果我们使用普通的请求方式,每次请求都需要重新提供用户名和密码进行验证,这显然是非常繁琐且不现实的。而使用session,我们只需在第一次登录时进行身份验证,之后session会自动保存服务器返回的cookie,并在后续的请求中带上这个cookie,服务器通过验证cookie就能识别我们的身份,从而实现登录状态的保持,让我们能够访问那些需要登录才能访问的页面。
2. 使用 session 发送请求

下面以模拟登录知乎为例,展示如何使用session发送请求实现登录后的页面访问。

首先,我们需要分析知乎的登录过程,获取登录所需的参数和 URL。在登录过程中,知乎会要求我们提供用户名、密码以及一个名为_xsrf的参数,这个参数可以从登录页面的 HTML 源代码中获取。

import requests
import re


def get_xsrf_token(session):
    url = 'https://www.zhihu.com'
    response = session.get(url)
    match_obj = re.search('.*name="_xsrf" value="(.*?)"', response.text)
    if match_obj:
        return match_obj.group(1)
    else:
        return ""


def zhihu_login(account, password):
    session = requests.Session()
    agent = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"
    headers = {
        "Host": "www.zhihu.com",
        "Referer": "https://www.zhihu.com/",
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": agent
    }
    session.headers = headers

    _xsrf = get_xsrf_token(session)
    post_data = {}
    post_url = ""
    if re.match("^1\d{10}$", account):
        print("phone login")
        post_url = "https://www.zhihu.com/login/phone_num"
        post_data = {
            "_xsrf": _xsrf,
            "phone_num": account,
            "password": password
        }
    else:
        if "@" in account:
            print("email login")
            post_url = "https://www.zhihu.com/login/email"
            post_data = {
                "_xsrf": _xsrf,
                "email": account,
                "password": password
            }

    response = session.post(post_url, data=post_data)
    print(response.text)

    # 登录成功后,访问需要登录才能访问的页面
    profile_url = "https://www.zhihu.com/people/your_profile_name"
    response = session.get(profile_url)
    print(response.text)


if __name__ == "__main__":
    account = "your_account"
    password = "your_password"
    zhihu_login(account, password)

在上述代码中:

  • 首先定义了get_xsrf_token函数,该函数接收一个session对象作为参数,通过发送 GET 请求获取知乎首页的内容,并使用正则表达式从页面中提取_xsrf参数的值。
  • 然后在zhihu_login函数中,创建了一个session对象,并设置了请求头信息,以模拟真实的浏览器访问。
  • 根据输入的账号类型(手机号码或邮箱),构造相应的登录 URL 和 POST 数据,其中包含了_xsrf参数、账号和密码。
  • 使用session.post方法发送登录请求,服务器验证成功后会返回包含登录状态的响应。
  • 登录成功后,使用session.get方法访问知乎个人主页(需替换为真实的个人主页链接),由于session已经保存了登录后的cookie,所以可以成功访问该页面,并打印出页面内容。

通过以上示例,我们可以看到session在模拟登录和保持会话状态方面的强大功能,它极大地简化了我们与需要身份验证的网站进行交互的过程。

(二)证书验证

  1. https 协议与证书验证

https协议是在http协议的基础上,通过添加 SSL/TLS 加密层来实现数据传输的安全性。在https通信中,证书扮演着至关重要的角色。证书是由受信任的数字证书颁发机构(CA,Certificate Authority)颁发的,它包含了服务器的公钥、证书所有者信息、证书有效期、颁发机构签名等内容。

当客户端(如浏览器或使用requests模块的程序)与服务器建立https连接时,会进行以下步骤的证书验证:

  • 客户端向服务器发送请求,服务器将其数字证书返回给客户端。
  • 客户端验证证书的有效性,包括检查证书是否在有效期内、证书的用途是否与请求的站点匹配、证书是否在证书吊销列表(CRL,Certificate Revocation List)中、证书的颁发机构是否受信任等。这是一个递归的过程,直到验证到根证书(操作系统或浏览器内置的受信任的根证书)。
  • 如果证书验证通过,客户端继续与服务器进行通信;如果验证不通过,客户端会显示警告信息,提示用户连接可能存在风险。

证书验证的目的是确保客户端与真正的目标服务器进行通信,防止中间人攻击。中间人攻击是指攻击者在客户端和服务器之间插入自己,截获、篡改或伪造通信数据。通过证书验证,客户端可以验证服务器的身份,保证数据传输的安全性和完整性。

  1. requests 中的证书验证设置

在requests模块中,使用requests.get()等方法发送https请求时,默认会验证服务器的证书。通过verify参数可以控制证书验证的行为。

  • 跳过验证(设为 False):在某些情况下,如访问的是测试环境的服务器,其证书可能是自签名的,不受信任的证书颁发机构颁发的,此时可以将verify参数设置为False来跳过证书验证。例如:
import requests

url = 'https://self_signed_server.example.com'
response = requests.get(url, verify=False)
print(response.text)

需要注意的是,跳过证书验证会降低通信的安全性,存在被中间人攻击的风险。因此,在生产环境中,应谨慎使用此设置,确保访问的服务器是可信任的。

  • 指定证书路径进行验证:如果服务器使用的是自定义的证书,而不是受信任的 CA 颁发的证书,我们可以通过指定证书路径来进行验证。假设我们有一个本地的 CA 证书文件ca_cert.pem,可以这样设置:
import requests

url = 'https://custom_cert_server.example.com'
cert_path = 'ca_cert.pem'
response = requests.get(url, verify=cert_path)
print(response.text)

在上述代码中,verify参数被设置为证书文件的路径,requests模块会使用该证书来验证服务器的证书,确保通信的安全性。

(三)设置代理

  1. 代理的作用和原理

代理服务器是位于客户端和目标服务器之间的一台服务器,它的作用是代理网络用户去获取网络信息。形象地说,它就像是网络信息的中转站。当我们设置了代理服务器后,本机不再直接向目标服务器发起请求,而是向代理服务器发出请求。代理服务器接收到请求后,会将请求转发给目标服务器,目标服务器处理请求后将响应返回给代理服务器,最后代理服务器再将响应转发给本机。

在爬虫等场景中,使用代理主要有以下几个原因:

  • 避免 IP 被封:许多网站会对频繁访问的 IP 地址进行限制或封禁,以防止恶意爬虫等行为。通过使用代理服务器,我们可以不断更换请求的 IP 地址,分散请求来源,从而降低被封禁的风险。
  • 突破访问限制:有些网站可能会根据 IP 地址的地理位置、所属网络等因素限制访问。使用代理服务器,我们可以获取不同地区、不同网络的 IP 地址,从而突破这些访问限制,访问到原本无法访问的资源。
  • 提高访问速度:一些代理服务器会设置较大的硬盘缓冲区,当有外界的信息通过时,会将其保存到缓冲区中。当其他用户再访问相同的信息时,代理服务器可以直接从缓冲区中读取信息并传给用户,从而提高访问速度。
  1. 在 requests 中设置代理

在requests模块中,通过proxies参数来设置代理。以下是设置 HTTP 和 HTTPS 代理的示例:

import requests

url = 'https://www.example.com'
proxies = {
    'http': 'http://proxy_ip:proxy_port',
    'https': 'https://proxy_ip:proxy_port'
}
response = requests.get(url, proxies=proxies)
print(response.text)

在上述代码中,proxies是一个字典,其中http和https分别表示 HTTP 和 HTTPS 协议的代理地址,proxy_ip和proxy_port分别是代理服务器的 IP 地址和端口号。

如果代理服务器需要用户名和密码进行认证,可以这样设置:

import requests

url = 'https://www.example.com'
proxies = {
    'http': 'http://username:password@proxy_ip:proxy_port',
    'https': 'https://username:password@proxy_ip:proxy_port'
}
response = requests.get(url, proxies=proxies)
print(response.text)

在实际应用中,为了提高爬虫的稳定性和效率,我们还可以将多个代理 IP 地址放入一个列表中,并在每次请求时随机选择一个代理,以避免单个代理 IP 被频繁使用而导致被封禁。例如:

import requests
import random


url = 'https://www.example.com'
proxy_list = [
    'http://proxy1_ip:proxy1_port',
    'http://proxy2_ip:proxy2_port',
    'http://proxy3_ip:proxy3_port'
]
proxy = {
    'http': random.choice(proxy_list),
    'https': random.choice(proxy_list)
}
response = requests.get(url, proxies=proxy)
print(response.text)

通过以上设置代理的方法,我们可以灵活地利用代理服务器来满足各种网络请求的需求,提高程序的可用性和安全性。

四、实战案例

(一)简单网页爬虫

  1. 需求分析

假设我们要爬取豆瓣电影 Top250 页面(https://movie.douban.com/top250)的电影信息,包括电影名称、评分、评价人数以及电影简介。该页面的结构较为规整,电影信息都包含在div标签且class为item的元素中。每个item元素里,电影名称在span标签且class为title的元素中,评分在span标签且class为rating_num的元素中,评价人数在span标签且class为pl的元素中,电影简介在span标签且class为inq的元素中。我们的目标就是从这个网页中提取出这些信息。

  1. 代码实现
import requests
from bs4 import BeautifulSoup


def crawl_douban_movies():
    url = 'https://movie.douban.com/top250'
    headers = {
        'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        movie_items = soup.find_all('div', class_='item')
        for item in movie_items:
            movie_name = item.find('span', class_='title').text
            rating = item.find('span', class_='rating_num').text
            comment_num = item.find('span', class_='pl').text.strip('()')
            quote = item.find('span', class_='inq')
            quote = quote.text if quote else '无简介'
            print(f'电影名称: {movie_name}')
            print(f'评分: {rating}')
            print(f'评价人数: {comment_num}')
            print(f'简介: {quote}')
            print('-' * 50)
    else:
        print(f'请求失败,状态码: {response.status_code}')


if __name__ == "__main__":
    crawl_douban_movies()

在上述代码中:

  • 首先定义了目标 URL 和请求头,请求头中的User - Agent用于模拟浏览器访问,避免被网站识别为爬虫而拒绝访问。
  • 使用requests.get()方法发送 GET 请求获取网页内容,并检查响应状态码。如果状态码为 200,表示请求成功。
  • 利用BeautifulSoup库将响应的文本内容解析为 HTML 文档对象,方便后续的数据提取。
  • 通过find_all()方法找到所有包含电影信息的div元素,然后在每个元素中,使用find()方法找到对应的电影名称、评分、评价人数和简介的元素,并提取其文本内容。最后将提取到的信息打印输出。

(二)模拟登录网站

  1. 模拟登录流程分析

以知乎为例,模拟登录的流程如下:

  • 获取登录页面:首先发送 GET 请求到知乎的登录页面(https://www.zhihu.com/signin),获取登录页面的 HTML 内容。这个页面中包含了登录所需的一些参数,如_xsrf,以及可能出现的验证码图片链接。
  • 解析登录表单:使用BeautifulSoup等解析库解析登录页面的 HTML,找到登录表单中的各个字段,如用户名、密码、_xsrf等。其中,_xsrf是一个用于防止跨站请求伪造(CSRF)的令牌,每次页面加载时都会动态生成,需要从页面中提取出来并在登录请求中发送。
  • 处理验证码(如有):如果登录页面存在验证码,需要识别验证码。可以使用第三方的 OCR(光学字符识别)库,如ddddocr来识别验证码图片中的字符。首先发送 GET 请求获取验证码图片的二进制内容,并保存为本地文件,然后使用 OCR 库对图片进行识别,得到验证码的文本。
  • 发送登录请求:构造登录请求的数据,包括用户名、密码、_xsrf以及验证码(如果有),使用requests.post()方法发送 POST 请求到知乎的登录接口(https://www.zhihu.com/api/v3/oauth/sign_in)。登录成功后,服务器会返回一个包含用户信息和登录状态的响应,同时设置一些cookies,这些cookies用于保持用户的登录状态。
  1. 代码实现与注意事项
import requests
from bs4 import BeautifulSoup
import ddddocr


def zhihu_login(account, password):
    session = requests.Session()
    headers = {
        'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    session.headers = headers

    # 获取登录页面
    login_url = 'https://www.zhihu.com/signin'
    response = session.get(login_url)
    if response.status_code!= 200:
        print(f'获取登录页面失败,状态码: {response.status_code}')
        return

    soup = BeautifulSoup(response.text, 'html.parser')
    _xsrf = soup.find('input', attrs={'name': '_xsrf'})['value']

    # 处理验证码
    captcha_url = 'https://www.zhihu.com/api/v3/oauth/captcha?lang=cn'
    response = session.get(captcha_url)
    if response.json()['show_captcha']:
        response = session.get(captcha_url, params={'type': 'login'})
        with open('captcha.jpg', 'wb') as f:
            f.write(response.content)
        ocr = ddddocr.DdddOcr()
        with open('captcha.jpg', 'rb') as f:
            img_bytes = f.read()
        captcha = ocr.classification(img_bytes)
    else:
        captcha = ''

    # 发送登录请求
    login_data = {
        'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
        'grant_type': 'password',
        'source': 'com.zhihu.web',
        'username': account,
        'password': password,
        '_xsrf': _xsrf,
        'captcha': captcha,
        'lang': 'cn',
        'ref_source': 'homepage'
    }
    response = session.post('https://www.zhihu.com/api/v3/oauth/sign_in', data=login_data)
    if response.status_code == 200:
        print('登录成功')
        # 可以在此处进行登录后的操作,如访问需要登录才能访问的页面
        profile_url = 'https://www.zhihu.com/people/your_profile_name'
        response = session.get(profile_url)
        print(response.text)
    else:
        print(f'登录失败,状态码: {response.status_code},原因: {response.text}')


if __name__ == "__main__":
    account = 'your_account'
    password = 'your_password'
    zhihu_login(account, password)
  • 注意事项
    • 动态参数处理:_xsrf等参数是动态变化的,每次获取登录页面时都需要重新提取,确保登录请求中携带的参数是最新的。
    • 验证码处理:验证码的识别准确率可能受到图片质量、验证码类型等因素的影响。如果识别失败,可以尝试使用更高级的 OCR 技术或人工识别的方式。同时,知乎等网站可能会对验证码的识别进行反制,如增加验证码的复杂度、限制验证码的获取次数等,需要根据实际情况进行调整。
    • session 的使用:使用requests.Session()对象来保持会话状态,这样在发送登录请求后,session会自动保存服务器返回的cookies,后续的请求会自动带上这些cookies,从而实现登录状态的保持,方便进行登录后的操作,如访问个人主页、收藏页面等。

五、总结与展望

在 Python 的网络编程领域中,requests模块无疑是一颗璀璨的明星。通过本文的学习,我们深入了解了requests模块的核心知识点和丰富的使用技巧。从最基础的安装与导入,到发送各种类型的 HTTP 请求,如 GET、POST,再到对响应内容的多样化处理,包括获取文本、二进制数据、JSON 数据以及响应状态码等,我们逐步掌握了requests模块的基本操作。

在高级应用方面,requests模块同样展现出了强大的功能。会话维持(session)功能使得我们能够轻松地在多个请求之间保持状态,实现如模拟登录后访问受限页面等操作;证书验证机制确保了在https通信中的安全性,让我们能够放心地与服务器进行数据交互;而设置代理功能则为我们突破网络限制、避免 IP 被封等提供了有力的支持。

通过简单网页爬虫和模拟登录网站这两个实战案例,我们将requests模块的知识应用到了实际项目中,进一步加深了对其的理解和掌握。在网页爬虫案例中,我们利用requests模块获取网页内容,并结合BeautifulSoup库进行数据解析,成功地提取出了所需的信息;在模拟登录网站案例中,我们详细分析了登录流程,通过处理动态参数、验证码等,实现了对知乎等网站的模拟登录,充分展示了requests模块在实际场景中的应用价值。

然而,requests模块的潜力远不止于此。在未来的学习和实践中,读者可以进一步探索其高级用法和优化策略。例如,在处理大量并发请求时,可以研究如何利用requests模块结合多线程、异步编程等技术来提高效率;在与复杂的 API 进行交互时,深入了解如何更好地处理请求头、请求体以及各种响应状态,以确保数据的准确传输和高效处理。同时,随着网络技术的不断发展,requests模块也在持续更新和完善,读者可以关注其官方文档和社区动态,及时掌握新的功能和特性,将其更好地应用到实际项目中。希望大家能够在实际项目中充分发挥requests模块的优势,创造出更多有价值的应用。


http://www.kler.cn/a/546797.html

相关文章:

  • 遵循规则:利用大语言模型进行视频异常检测的推理
  • DeepSeek v3 技术报告阅读笔记
  • spring 中 AspectJ 基于 XML 的实现分析
  • 安全启动(secure boot)怎么关闭_史上最全的各品牌机和组装机关闭安全启动教程
  • 将错误消息输出到标准错误流:Rust中的最佳实践
  • web第三次作业
  • 浏览器安全学习
  • 中兴R5300 G4服务器配置磁盘RAID
  • 人工智能之知识图谱实战系列
  • 三格电子——TCP转ProfibusDP网关使用场景
  • 从技术债务到架构升级,滴滴国际化外卖的变革
  • [0696].第11节:Kafka-Eagle监控
  • dayjs的isSameOrAfter、isSameOrBefore、isAfter、isBefore学习
  • 微软AutoGen高级功能——Selector Group Chat
  • 【webview Android】视频获取首帧为封面
  • 服务器防护(ubuntu)
  • 辛格迪客户案例 | 钥准医药科技GMP文件管理(DMS)项目
  • oracle 19c安装DBRU补丁时报错CheckSystemSpace的处理
  • 百度 AI开源!将在6月30日开源文心大模型4.5系列
  • 上下文编辑器在不同场景下的功能(含使用案例)