21.7 Python 使用Request库
Request库可以用来发送各种HTTP请求,该框架的特点是简单易用,同时支持同步和异步请求,支持HTTP协议的各种方法和重定向。它还支持Cookie、HTTPS和认证等特性。 Request库的使用非常广泛,可以用于网络爬虫、API调用、网站测试等场景。
读者如果需要使用这个库,同样需要执行pip命令用以安装:
- 安装PIP包:pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
在开始使用之前,我们需要编写一个简单的生成随机User-Agent的函数,User-Agent是一个HTTP协议头部,用于标识请求的客户端身份信息,包括客户端的应用软件、操作系统、硬件设备等信息。服务器可以通过User-Agent头部信息来确定客户端的类型,并针对不同类型的客户端提供不同的服务或页面展现效果。
对于爬虫来说我们并不希望固定这个值,而是希望每次调用时都会产生一个新的随机值,以此来实现每次访问固定页面时使用不同的User-Agent头,并且让Referer头也保持每次随机化,通过这种方式可以在一定程度上缓解反爬机制,如下则是实现随机请求体的实现代码;
import random
# 随机获取一个请求体
def GetUserAgent(url):
UsrHead = ["Windows; U; Windows NT 6.1; en-us", "Windows NT 5.1; x86_64", "Ubuntu U; NT 18.04; x86_64",
"Windows NT 10.0; WOW64", "X11; Ubuntu i686;", "X11; Centos 8 x86_64;",
"compatible; MSIE 9.0; Windows NT 8.1;",
"X11; SuUSE Linux i686", "Macintosh; U; Intel Mac OS X 10_6_8; en-us",
"compatible; MSIE 7.0; Windows Server 6.1",
"Macintosh; Intel Mac OS X 10.6.8; U; en", "compatible; MSIE 6.0; Windows NT 5.1", "iPad; CPU OS 4_3_3;",
"Windows NT 10.0; WOW64; rv:38.0", "Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C;",
"MSIE 10.0; Windows NT 6.1;",
"iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X;", "iPod; U; CPU iPhone OS 4_3_3 like Mac OS X;",
"Linux; U; Android 6.0;","Linux; U; Android 9.0;","Linux; U; Android 7.1;","Linux; U; Android 10.0;"
"Linux; U; Nexus One Build/FRF91", "BlackBerry; U; BlackBerry 9800;","BlackBerry; U; BlackBerry 7800;"
"hp-tablet; Linux; hpwOS/3.0.0; U; en-US",
"SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019;",
"compatible; MSIE 9.1; Windows Phone OS 7.5; IEMobile/9.0; HTC;"]
UsrFox = ["Chrome/70.0.3100.0", "Auburn Browser/10.05", "Safari/522.13", "Chrome/80.0.1211.0",
"Firefox/74.0 Safari/522.13",
"Gecko/20100101 Firefox/4.0.1", "Presto/2.8.131 Version/11.11", "Mobile/8J2 Safari/6533.18.5",
"Mobile/10 Safari/8536.25",
"Version/4.0 Safari/534.13", "wOSBrowser/233.70 Baidu Browser/534.6 TouchPad/1.0",
"BrowserNG/7.1.18124 Safari/522.13",
"rident/4.0; SE 2.X MetaSr 1.0;", "360SE/80.1 ", "wOSBrowser/233.70", "UCWEB7.0.2.37/28/999",
"Opera/UCWEB7.0.2.37 Safari",
"Chrome/80.0.3987.149 Safari/537.36", "Gecko/20100101 Firefox/74.0",
"Trident/7.0; rv:11.0) like Gecko Safari/522.13"]
UsrAgent = "Mozilla/5.0 (" + str(random.sample(UsrHead, 1)[0]) + ") AppleWebKit/" + str(
round(random.uniform(100, 600), 2)) \
+ " (KHTML, like Gecko) " + str(random.sample(UsrFox, 1)[0])
UsrRefer = str(url + "/" + "id_" + "".join(random.sample("1234567890", 6)) + ".html")
UserAgent = {"User-Agent": UsrAgent, "Referer": UsrRefer}
return UserAgent
if __name__ == "__main__":
ref = GetUserAgent("https://www.lyshark.com")
print("User-Agent: ",ref.get("User-Agent"))
print("Referer: ",ref.get("Referer"))
如下输出效果,我们通过传入一个参数,即可输出一条随机请求头,及一个来源地址,输出效果如下所示;

21.7.1 实现GET请求
HTTP GET请求是一种常见的HTTP请求方法之一,用于向服务器请求特定资源,比如网页、图片、视频等。在HTTP GET请求中,客户端向服务器发送一个带有请求参数的URL,服务器接收到请求后返回请求的资源。
要实现访问一个页面可以调用requests.get()函数,该函数可用于发送http以及https请求,并返回相应结果,该方法的语法如下所示;
requests.get(url, params=None, **kwargs)
其中,url是要请求的URL,params是可选的参数,可以包含查询字符串参数,**kwargs是任意的关键字参数,它们将被转换为HTTP请求头。这些参数包括但不限于:
- headers: 字典类型,
HTTP请求头 - cookies: 字典或
CookieJar类型,请求中发送的cookie - auth: 元组类型,支持
HTTP身份验证 - timeout: 超时时间,单位为秒
- allow_redirects: 允许重定向,True或False
- proxies: 字典类型,代理服务器URL
- verify: 是否验证
SSL证书,True或False
该方法返回一个响应对象,可以使用该对象访问HTTP响应状态码、响应头、响应正文等信息,如下一个案例则是一个简单实现访问特定页面的功能。
import re
import requests
header = {
'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
'referer': 'https://www.baidu.com'
}
if __name__ == "__main__":
ret = requests.get(url="https://www.lyshark.com", headers=header, timeout=5)
print("输出请求头: ", ret.headers)
print("服务器类型: ", ret.headers.get("Server"))
print("服务器时间: ", ret.headers.get("Date"))
# 检查是否访问成功
if ret.status_code == 200:
title = re.findall('<title>(.+)</title>', ret.text)
print("输出标题: ", title)
运行上述代码即可实现访问www.lyshark.com服务器,并返回该服务器的相关参数信息,如下图所示;

21.7.2 实现POST请求
HTTP POST请求是指客户端向服务器提交数据的请求方式。在POST请求中,提交的数据会被包含在HTTP请求体中,并且请求头中会包含Content-Type字段来指定提交的数据格式。与GET请求相比,POST请求更适用于需要向服务器提交大量数据、敏感数据或需要修改服务器状态的场景。
要实现POST请求,读者可调用requests.post函数,该函数用于向指定的URL发送HTTP POST请求。通过POST请求,客户端可以向服务器传递数据,这些数据存储在请求的正文中。与GET请求不同,POST请求不会将数据附加在URL参数中。下面是requests.post的语法:
requests.post(url, data=None, json=None, **kwargs)
其中,参数url是POST请求的目标URL。参数data是POST请求的正文数据,类型为字符串或字节流。参数json是一个Python对象,表示要发送的JSON数据。其他的关键字参数将作为请求头的一部分发送。
import requests
if __name__ == "__main__":
headers = {
"content-type": "application/json",
"Authorization": "",
"Cookie": "",
"Host": ""
}
data = {"username": "lyshark", "tel": "18611184241"}
req = requests.post(url="https://www.lyshark.com/api", headers=headers, data=data)
print("响应结果: ",req)
如上一段代码,通过使用post函数,并在调用时传入一个data字典,此时在发送请求时会默认携带该字典传递,运行后如果对端相应了则会返回状态码。

21.7.3 使用HTTP代理
HTTP代理是一个允许用户将其计算机流量通过另一台服务器进行传输的网络服务。通过使用代理服务器,用户可以隐藏其真实IP地址和位置,从而增加其在互联网上的匿名性。HTTP代理通常可以用于访问被阻止的网站、绕过网络过滤器和提高用户隐私。可以通过设置代理服务器地址和端口来在请求中使用HTTP代理。
在requests库中同样支持增加代理功能,代理的写法有两种分别是有密码与无密码,这两种格式可写为:
- 有密码写法:"https": "https://username:password@ip:port"
- 无密码写法:"http": "http://ip:port"
在使用代理时,我们只需要在调用requests.get请求时增加一个proxies字段并指定一个字典,该字典内存放我们的代理地址即可,这些代理地址可以在网络中很容易的获取到。
import json
import requests
header = {
'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
'referer': 'https://www.baidu.com'
}
proxy = { 'http': 'http://112.54.47.55:9091'}
if __name__ == "__main__":
ret = requests.get(url="http://httpbin.org/get", headers=header, proxies=proxy, timeout=5)
ret.encoding = "utf-8"
# 检查是否访问成功
if ret.status_code == 200:
load = json.loads(ret.text)
print("当前自身IP地址:",load.get("origin"))
如上则是一段使用代理访问目标地址的代码,当使用代理成功后其返回值应该与代理地址保持一致,如下图所示;

代理地址的获取有许多,此处我们可以使用如下所示的一个代理地址,该项目是一个长期项目代理地址每天都会更新,读者可自行打开查阅;
当然要想使用这些代理不转换肯定是不行的,我们可以通过编程的方式将这些代理根据自己所需要的格式进行转换,将其转换为可以直接在代码中引用的,如下则是一种简单的转换流程;
import json
import requests
header = {'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',}
# 获取代理并返回字典
def GetProxy():
ref_dict = {"http":[], "https":[]}
ret = requests.get(url="http://proxylist.fatezero.org/proxy.list", headers=header, timeout=5)
ret.encoding = "utf-8"
# 检查是否访问成功
if ret.status_code == 200:
# 切割并将代理地址逐个处理
local_address_list = ret.text.split("\n")
for index in local_address_list:
try:
dict = eval(index)
if len(dict["export_address"]) != 0 and dict["export_address"][0] != "unknown":
address = dict["export_address"][0]
port = dict["port"]
type = dict["type"]
if type == "http":
insert = f"http://{address}:{port}"
ref_dict["http"].append(insert)
if type == "https":
insert = f"https://{address}:{port}"
ref_dict["https"].append(insert)
except Exception:
pass
return ref_dict
if __name__ == "__main__":
proxy_list = GetProxy()
print(proxy_list)
读者可运行上述代码,此时即可将网页中的字符串转换为可以被直接使用的代理地址,输出效果图如下所示;

这些代理地址可能由于时间关系不保证全部能用,接着我们还需要实现一个CheckProxy函数,该函数用于验证这些代理地址的可用性,实现代码如下所示;
import json
import requests
# 验证代理是否存活
def CheckProxy(proxy):
http = proxy["http"]
for index in http:
try:
proxy = {'http': 'http://127.0.0.1:8080'}
proxy.update({'http': index})
ret = requests.get(url="http://httpbin.org/get", headers=header, proxies=proxy, timeout=5)
# 检查是否访问成功
if ret.status_code == 200:
load = json.loads(ret.text)
print("代理头部: {} 实际访问时的地址: {}".format(index,load.get("origin")))
except Exception:
pass
if __name__ == "__main__":
proxy_list = GetProxy()
CheckProxy(proxy_list)
代码验证原理则是通过调用requests.get函数访问http://httpbin.org/get当代理地址与当前地址一致则说明该地址是可用的,通过循环的方式不断验证即可得到一批可用地址,如下图所示;

21.7.4 下载页面数据
有时候我们需要保存一个HTTP页面或保存页面中的特定图片等元素,此时就需要自己实现页面的下载功能,针对网页的下载可以直接使用requests.get()函数默认参数即可,而当需要下载大文件或者是图片资源时,我们可以在调用该函数时,增加一个stream=True属性,该属性预示着将会采用流模式,此时就可以通过iter_content迭代器迭代下载整个图片。
首先我们先来实现下载页面功能,该函数封装为download_page()在执行时接收两个参数,分别是需要下载的页面网址,以及需要保存的文件名,当执行下载成功后则会返回response.status_code状态码。
import os
import requests
header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0"}
# 下载页面到本地
def download_page(url,path,timeout):
params = {"encode": "utf-8"}
try:
response = requests.get(url=url, params=params, headers=header, timeout=timeout)
# 如果返回200
if response.status_code == 200:
# print("网页编码方式: {} -> {}".format(response.encoding, response.apparent_encoding))
context = response.text.encode(response.encoding).decode(response.apparent_encoding, "ignore")
# 检查文件不存在
if os.path.exists(path) == False:
# 将文件保存
with open(path,"w",encoding=response.apparent_encoding) as file_point:
ref = file_point.write(context)
# 验证是否保存
if ref != 0 or ref != None:
return ref
else:
return 0
# 如果文件存在则
else:
return 0
else:
return response.status_code
except Exception:
return 0
return 0
if __name__ == "__main__":
# 下载页面到本地为index.html设置超时时间5秒
down_page = download_page("https://www.lyshark.com","index.html",5)
if down_page != 0:
print("下载文件完成,返回代码: {}".format(down_page))
我们以下载www.lyshark.com主页为例,当执行后读者可看到如下图所示的输出结果;

接着是针对图片的下载,下载图片可以调用download_picture()函数,该函数传入三个参数,分别是需要下载的图片路径,保存图片的路径,以及设置一个超时时间。
import os
import requests
header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0"}
# 下载页面到本地
def download_picture(url,path,timeout):
params = {"encode": "utf-8"}
try:
img_download = requests.get(url=url, params=params, headers=header, timeout=timeout,stream=True)
# 如果返回200
if img_download.status_code == 200:
# 检查文件不存在
if os.path.exists(path) == False:
# 将图片保存
with open(path,"wb") as file_point:
# 流的方式保存,每次保存1024
chunk_size = 0
for chunk in img_download.iter_content(chunk_size=1024):
size = file_point.write(chunk)
chunk_size = chunk_size + size
print("[+] chunk = {}".format(chunk_size))
return chunk_size
# 如果文件存在则
else:
return 0
else:
return img_download.status_code
except Exception:
return 0
return 0
if __name__ == "__main__":
# 下载图片到本地
down_picture = download_picture("https://www.lyshark.com/images/baidu_logo.png","security.png",5)
if down_picture != 0:
print("下载文件完成,返回代码: {}".format(down_picture))
运行上述代码,将下载www.lyshark.com下面的图标,并将该图标保存为security.png,输出效果如下图所示;

21.7 Python 使用Request库的更多相关文章
- 在Python中用Request库模拟登录(一):字幕库(无加密,无验证码)
字幕库的登录表单如下所示,其中省去了无关紧要的内容: <form class="login-form" action="/User/login.html" ...
- Python 基于request库的get,post,delete,封装
# coding=utf-8 import json import requests class TestApi(object): """ /* @param: @ses ...
- 基于python的request库,模拟登录csdn博客
以前爬虫用urllib2来实现,也用过scrapy的爬虫框架,这次试试requests,刚开始用,用起来确实比urllib2好,封装的更好一些,使用起来简单方便很多. 安装requests库 ...
- 在Python中用Request库模拟登录(四):哔哩哔哩(有加密,有验证码)
!已失效! 抓包分析 获取验证码 获取加密公钥 其中hash是变化的,公钥key不变 登录 其中用户名没有被加密,密码被加密. 因为在获取公钥的时候同时返回了一个hash值,推测此hash值与密码加密 ...
- 在Python中用Request库模拟登录(三):Discuz论坛(未加密,有验证码,有隐藏验证)
以Discuz的官方站为例.直接点击网页右上角的登录按钮,会弹出一个带验证码的登录窗口.输入验证码之后,会检查验证码是否正确.然后登录.首先,通过抓包分析,这些过程浏览器和服务器交换了哪些数据. 抓包 ...
- Python request库与爬虫框架
Requests库的7个主要方法 requests.request():构造一个请求,支持以下各方法的基础方法 requests.get():获取HTML网页的主要方法,对应于HTTP的GET ...
- Python网络爬虫与信息提取[request库的应用](单元一)
---恢复内容开始--- 注:学习中国大学mooc 嵩天课程 的学习笔记 request的七个主要方法 request.request() 构造一个请求用以支撑其他基本方法 request.get(u ...
- Python virtualenv安装库报错SSL: CERTIFICATE_VERIFY_FAILED
Python virtualenv安装库报错SSL: CERTIFICATE_VERIFY_FAILED 问题描述 使用pip按照virtualenv报错,如下: pip install virtua ...
- 【python】标准库的大致认识
正如那句 Python 社区中很有名的话所说的:“battery included”,Python 的一大好处在于它有一套很有用的标准库(standard library).标准库是随着 Python ...
- python的urllib2库详细使用说明
一直以来技术群里会有新入行的同学提问关于urllib和urllib2以及cookielib相关的问题.所以我打算在这里总结一下,避免大家反复回答同样的问题浪费资源. 这篇属于教程类的文字,如果你已经非 ...
随机推荐
- Multisim 14 免费破解版,下载安装教程,2023年亲测可用,永久激活
Multisim是一款功能强大.操作流畅的专业仿真工具,适用于板级模拟/数字电路板设计工作,提供电路原理图图形输入.电路硬件描述语言输入,具有丰富的仿真分析能力.拥有专业版和教学版,深受国内外教师.科 ...
- KMP 复习笔记
KMP 学习(复习)笔记 KMP(Knuth-Morris-Pratt)是算法竞赛中常用的字符串匹配算法之一,它可以有效地利用失配信息来使得匹配全过程中不回溯,从而在线性时间内完成匹配. 本文已有前置 ...
- Codeforces Round #700 (Div. 2) A ~ D1个人题解
Codeforces Round #700 (Div. 2) 比赛链接: Click Here 1480A. Yet Another String Game 因为Alice是要追求小,Bob追求大值, ...
- Java 21新特性-虚拟线程 审核中
本文翻译自国外论坛 medium,原文地址:https://medium.com/@benweidig/looking-at-java-21-virtual-threads-0ddda4ac1be1 ...
- freeswitch的2833和inband对接方案
概述 freeswitch支持三种模式的DTMF传输方式,分别时inband.INFO.2833. 在传统的PSTN网络中,所有的DTMF码都是inband模式,所以VOIP网络和PSTN网络对接中, ...
- C#设计模式11——享元模式的写法
1. 什么是享元模式? 享元模式是一种结构型设计模式,目的是通过共享对象来尽量减少内存使用和对象数量.它通过将对象分为可共享的和不可共享的来实现这一目的. 2. 为什么要使用享元模式? 使用享元模式可 ...
- python常见面试题讲解(十二)句子逆序
题目描述 将一个英文语句以单词为单位逆序排放.例如"I am a boy",逆序排放后为"boy a am I"所有单词之间用一个空格隔开,语句中除了英文字母外 ...
- java 服务 JVM 参数设置配置
本文为博主原创,转载请注明出处: 常用JVM 配置参数: -Xmx:表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/4大小. -Xms:表示java虚拟机堆区内存初始内存分配 ...
- ClickHouse的Join算法
ClickHouse的Join算法 ClickHouse是一款开源的列式分析型数据库(OLAP),专为需要超低延迟分析查询大量数据的场景而生.为了实现分析应用可能达到的最佳性能,分析型数据库(OLAP ...
- SD Host控制器的datasheet
SD-Host控制器的datasheet更多的是给嵌入式软件工作人员使用,datasheet中主要包含一些寄存器以及读写擦除流程 寄存器主要有: 控制寄存器 状态寄存器 配置寄存器 软件和硬件进行交互 ...