requests模块在爬虫程序中的应用相当广泛,可以说一个合格的爬虫工程师必须要掌握。
需要掌握的核心知识点:
- get请求
- post请求
- form表单参数
- params查询字符串参数
- json参数
- 请求头设置
- session会话
- cookie处理
- 代理设置
1.requests简介与安装
作用:发送网络请求,返回响应数据。
中文文档:https://requests.readthedocs.io/projects/cn/zh_CN/latest/
对于爬虫任务,使用 requests 模块基本能够解决绝大部分的数据抓取的任务。所以用好 requests 至关重要。
安装:
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
2.requests 发送网络请求以及常用属性
需求:通过 requests 向百度首页发送请求,获取百度首页数据
import requests
url="https://www.baidu.com"
response=requests.get(url=url)
print("---状态码如下---")
print(response.status_code)
print("---bytes类型数据---")
print(response.content)
print("---str类型数据---")
print(response.text)
print("---str类型数据(utf-8)---")
print(response.content.decode())
常用属性如下:
response.text
响应体str
类型respones.content
响应体bytes
类型response.status_code
响应状态码response.request.headers
响应对应的请求头response.headers
响应头response.request.headers.get('cookies')
响应对应请求的cookie
response.cookies
响应的cookie
(经过了set-cookie
动作)response.url
请求的URL
3. text 与 content 的区别
- response.text
- 类型:str
- 解码类型:requests 模块根据HTTP头部对响应的编码推测文本编码类型
- 修改编码方式:response.encoding='gbk'
- response.content
- 类型:bytes
- 解码类型:没有指定
- 修改解码方式:response.content.decode('utf-8')
获取网页源码的通用方式:
- response.encoding="utf-8"
- response.content.decode('utf-8')
- response.text
以上三种方式从前往后依次尝试,百分百可以解决网页编码问题。
4.下载网络图片
需求:将一张图片下载到本地
思路分析:
- 图片的url地址:https://q0.itc.cn/q_70/images03/20240705/22876c7f222e4f169a741a978543baae.jpeg
- 利用requests模块发送请求并获取响应
- 使用二进制写入的方式打开文件并将response响应内容写入文件内
import requests
# 图片的url
url="https://q0.itc.cn/q_70/images03/20240705/22876c7f222e4f169a741a978543baae.jpeg"
# 响应本身就是一个图片,并且是二进制类型
res=requests.get(url=url)
# 以二进制写入的方式打开文件
with open('篮球.jpeg','wb') as f:
f.write(res.content)
5.iter_content方法
如果下载一个较大的资源,例如一个视频,可能需要的下载时间比较长,在这个较长的下载过程中程序师不能做别的事情的(当然可以使用多任务来解决),如果在不是多任务的情况下,想要知道下载的进度,此时就可以通过类似迭代的方式下载部分资源。
1.使用 iter_content
在获取数据时,设置属性 stream=True
import requests
r=requests.get('https://www.baidu.com',stream=True)
with open('test.html','wb')as f:
for chunk in r.iter_content(chunk_size=100):
f.write(chunk)
2. stream=True 说明:
- 如果设置了 stream=True ,那么在强调 iter_content 方法时才会真正下载内容
- 如果没设置 stream 属性则调用 requests.get 就会耗费时间下载
3.显示视频下载进度
import requests
from tqdm import tqdm
def download_video(url,save_path):
res=requests.get(url=url,stream=True)
# 获取视频资源大小
total_video=int(res.headers.get('content-length',0))
# 初始化下载大小
download_size=0
# unit:下载单位(字节)
# unit_scale:自动调整单位
# unit_divisor:单位换算(除数为1024)
with open(save_path,'wb')as f,tqdm(total=total_video,unit='B',unit_scale=True,unit_divisor=1024)as bar:
for chunk in res.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
download_size+=len(chunk)
bar.update(len(chunk))
print('下载完成......')
# 调用下载函数
url='http://sns-bak-v2.xhscdn.com/stream/79/110/84/01e7bc015c4b355f4f0370019536666b8b_84.mp4'
save_path='./骑车.mp4'
download_video(url,save_path)
6.携带请求头
在请求某些网站时根据不同的浏览器会返回不同的响应内容,所以此时就需要根据需求来修改或添加请求头信息。
获取请求头与响应头:
import requests
response=requests.get("https://www.baidu.com")
# 响应头
print(response.headers)
# 请求头
print(response.request.headers)
定义 User-Agent:
headers={'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
携带请求头访问百度:
import requests
url="https://www.baidu.com"
header={'User-Agent': 'python-requests/2.31.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
res=requests.get(url=url,headers=header)
# 响应体
print(res.headers)
# 请求头
print(res.request.headers)
# 响应内容
print(res.text)
7.请求带有url查询参数的地址
我们在使用百度搜索的时候经常发现 url 地址中会有一个?,那么该问号后边的就是请求参数,又叫做查询字符串。如果想要做到自动搜索,就应该让发送出去的url携带参数。
示例地址:https://www.baidu.com/s?wd=python
# 1. 设置需要携带的查询字符串参数
kw = {'wd': 'java'}
# 2. 发送请求
response = requests.get('https://www.baidu.com/s', params=kw)
# 3.查看发送的URL
print(response.url)
当前查询字符串参数可以直接写到 url 地址中:
import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
url = 'https://www.baidu.com/s?wd=python'
# url中包含了请求参数,所以此时无需params
response = requests.get(url, headers=headers)
print("请求的URL:", response.url)
print("响应内容如下:", response.content)
8.使用requests发生post请求
在 HTTP 请求中,GET 和 POST 是使用最为频繁的请求方式。
- GET: 获取数据
- POST:提交数据
8.1 发送post请求
requests模块中能发送多种请求,例如:GET、POST、PUT、DELETE等等
发送post请求代码示例:
请求地址:http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice
import requests
from pprint import pprint
# 请求地址:http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice
url='http://www.cninfo.com.cn/new/disclosure'
headers={'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"}
data={
"column":"szse_latest",
"pageNum":"1",
"pageSize":"30",
"sortName":" ",
"sortType":" ",
"clusterFlag":"true",
}
res=requests.post(url,headers=headers,data=data)
pprint(res.json())
过程分析:
- 通过浏览器开发者工具获取当前网站数据API
- 查询载荷选项卡中的表单数据
- 构建表单数据
- 发送 post 请求
8.2 百度翻译(案例)
当前网站需要使用移动端的方式访问
请求地址: https://fanyi.baidu.com/#en/zh/
import requests
url='https://fanyi.baidu.com/sug'
headers={
'accept':'*/*',
'accept-encoding':'gzip, deflate, br, zstd',
'accept-language':'zh-CN,zh;q=0.9',
'cache-control':'no-cache',
'connection':'keep-alive',
'content-length':'21',
'content-type':'application/x-www-form-urlencoded',
'cookie':'__bid_n=18ab3cde1b71008e9fecb2; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1710903362,1710946795; PSTM=1711964404; BIDUPSID=CE8C6E709313A41A0518DB276E42F71D; BDUSS=k4QjFDaHVzNmZoNzBkV1BmQmR-Y3o3Si1ublNRdkUxZk1ieGh3Ym0wM1RrTkptRVFBQUFBJCQAAAAAAAAAAAEAAAC47d~2bmluZ21lbmdqaWVrb3UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANMDq2bTA6tmTV; BDUSS_BFESS=k4QjFDaHVzNmZoNzBkV1BmQmR-Y3o3Si1ublNRdkUxZk1ieGh3Ym0wM1RrTkptRVFBQUFBJCQAAAAAAAAAAAEAAAC47d~2bmluZ21lbmdqaWVrb3UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANMDq2bTA6tmTV; BAIDUID=47C72FDE7DE19C4D44A9EA48085663D3:FG=1; BAIDUID_BFESS=47C72FDE7DE19C4D44A9EA48085663D3:FG=1; BA_HECTOR=0g052k2g21ala1050h848h0hatfcl51jrmhdg1u; ZFY=6ec5yRPSHxFdPHKfEXMEkqHB2J9QngYNnrOu7eCTdmQ:C; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_WISE_SIDS=62037_62114_62176_62184_62187_62180_62195_62228; arialoadData=false; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=7; H_PS_PSSID=61027_61680_62114_62145_62167_62176_62184_62187_62180_62195_62235_62228_62259_62284; delPer=0; ab_sr=1.0.1_MTg2YjFiZTFkM2MwYTA4ZTMyZmYwNDYzMTM2MGU0YjM5YTk4MDMwOGY5NTllNDhhMzFjODgwMjY3OWE5ZDIwNWM2OTA5Y2I2M2EyOTY5YTEyN2VkZmQ2MjUzZGM5OTdhNTc5N2UxOWU0MGYxNDY0NWNhNTYyNTdkMDIwOWQyN2VjZTVkODdmYWFiMWRmNGRiYmQxOTY5MjFiZGRlNGE4OA==; RT="z=1&dm=baidu.com&si=1363a957-e52e-4d62-aada-106dae8cb6f0&ss=m7j492l9&sl=4&tt=6a4&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=2v0z"',
'host':'fanyi.baidu.com',
'origin':'https://fanyi.baidu.com',
'pragma':'no-cache',
'referer':'https://fanyi.baidu.com/mtpe-individual/multimodal',
'sec-ch-ua':'"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
'sec-ch-ua-mobile':'?0',
'sec-ch-ua-platform':'"Windows"',
'sec-fetch-dest':'empty',
'sec-fetch-mode':'cors',
'sec-fetch-site':'same-origin',
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
}
data={
"kw": "加油"
}
res=requests.post(url,headers=headers,data=data)
print(res.json()['data'][0]['v'].split(';')[0])
输出:
come on
9.requests处理cookie
为了能够通过爬虫获取到登录后的页面,或者是解决通过cookie的反爬,需要使用request来处理cookie相关的请求。
9.1 爬虫中使用cookie的利弊:
- 带上cookie的好处
- 能够访问登录后的页面
- 能够实现部分反反爬
- 带上cookie的坏处
- 一套cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫
- 那么上面的问题如何解决?使用多个账号
9.2 发送请求时添加cookie
1.cookie字符串放在headers中
# 将cookie添加到headers中
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 "
"(KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
"Cookie": 'BIDUPSID=07953C6101318E05197E77AFF3A49007; PSTM=1695298085; '
'ZFY=jAXoBNlaBGlHggda:BLlW8x7pEMyEhiZUIRbuQnnavss:C; '
'APPGUIDE_10_6_5=1; REALTIME_TRANS_SWITCH=1; '
'FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; '
'SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; '
'BAIDUID=37927E8274D89B902DEB6F1A024B3860:FG=1; '
'BAIDUID_BFESS=37927E8274D89B902DEB6F1A024B3860:FG=1; '
'RT="z=1&dm=baidu.com&si=ba30f04e-d552-4a5a-864f-1b2b222ff176&ss=lne882ji&sl=2&tt=1'
'ju&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=3pn&nu='
'1dzl78ujc&cl=3bd&ul=61c&hd=622"; BA_HECTOR=a12g8ka22421al2k80ak21a31ihvc081o; '
'BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; '
'Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1695476554,1696577209; '
'Hm_lvt_afd111fa62852d1f37001d1f980b6800=1695476565,1696577271; '
'Hm_lpvt_afd111fa62852d1f37001d1f980b6800=1696577271; Hm_lpvt_64e'
'cd82404c51e03dc91cb9e8c025574=1696577271; ab_sr=1.0.1_MjZiYjAyZTQ4OTZkNWU0Y2M'
'5YjQxMzZiOTE4Y2ZkOWNmMmI2MTNiMzhlOWQ0MTE4MzU0NDg5Njc5ZWU1ZDVkN2E4ZmM2Zjg3NjA5N2IwYWQ3OG'
'I3ZDBlYWJlMmFmODM3Y2FhZmJkYzgxY2EzZmI1NWRiZDgxNWMxOTU3ZjNhZTk3NzE0ZDg1OGY1MGM4YTM2ZjA1'
'ZTY4MGViOTI2OTlhYQ=='
}
headers中的cookie格式:
- 使用分号 ; 隔开
- 分号两边的类型 a=b 形式的表示一条cookie
- a=b 中, a表示键 name , b表示值 value
- 在 headers 中仅仅使用了 cookie 的name 和 value
2.把cookie字典传给请求方法的 cookies 参数接收
cookie_dict = {"cookie的name": "cookie的value"}
requests.get(url, headers=headers, cookies=cookie_dict)
3.使用requests提供的session模块
9.3 获取响应时提取 cookie
使用 requests 获取的 response 对象,具有 cookies 属性,能够获取对方服务器设置在本地的cookie,但是如何使用这些cookie呢?
使用 requests 模块提供的 response.cookies 方法。
- response.cookies 是 CookieJar 类型
- 使用 requests.utils.dict_from_cookiejar ,能够实现把 cookiejar 对象转化为字典
import requests
url='https://www.baidu.com'
# 发送请求,获取response
res=requests.get(url)
print(type(res.cookies))
# 使用方法从cookiejar中提取数据
cookies=requests.utils.dict_from_cookiejar(res.cookies)
print(cookies)
10.重定向与历史请求
测试代码:
import requests
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
}
r = requests.get("http://www.baidu.com", headers=headers)
print(r.url)
# 以上代码打印结果为:https://m.baidu.com/?from=844b&vit=fps
思考:为什么打印出来的 url 不是请求的 url 呢?
想要搞清楚这个问题,就要知道 requests 的重定向问题。
requests的默认情况:
默认情况下,requests 发送的请求除了方式为 HEAD 之外,其余的请求例如 GET、POST等都是能自动进行重定向的
这也就是为什么上面明明访问的是 http://www.baidu.com 而打印出来之后是 https://m.baidu.com/?from=844b&vit=fps 的原因
取消自动重定向:
在发送请求的时候,可以通过如下的设置,取消 requests 模块的自动重定向功能
requests.get(url,allow_redirects=False)
示例代码:
import requests
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
}
res = requests.get("http://www.baidu.com", headers=headers,allow_redirects=False)
print(res.status_code)
print(res.url)
默认情况下获取历史请求
通过 response.history 可以获取到请求的历史记录
import requests
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
}
# allow_redirects=False 可以取消重定向
res = requests.get("http://www.baidu.com", headers=headers,allow_redirects=False)
print(res.status_code)
print(res.url)
print("历史请求过程信息:")
print(res.history)
for one_info in res.history:
print(one_info.status_code, one_info.url, one_info.headers)
print("\n\n最后一次的请求信息:")
print(res.status_code, res.url, res.headers)
11.SSL证书问题(verify)
在浏览网页时,可能会遇到以下这种情况:
出现 这个问题的原因是:ssl证书不安全导致的。
在代码中发起请求的效果:
import requests
# 网站已无法正常访问, 可参考截图...
url = "https://chinasoftinc.com/owa"
response = requests.get(url)
print(response.text)
# 当前程序报错:ssl.CertificateError...
解决方案:
在代码中设置 verify 参数
import requests
url="https://chinasoftinc.com/owa"
res=requests.get(url,verify=False)
print(res.text)
12.请求超时(timeout)
在爬虫中,一个请求很久没有结果,就会让整个项目的效率变得非常低。这个时候我们就需要对请求进行强制要求,让它必须在特定的时间内返回结果,否则就报错。
超时参数的使用:
res=requests.get(url,timeout=3)
通过添加 timeout 参数,能够保证在三秒内返回响应,否则会报错
import requests
url="https://www.google.com"
res=requests.get(url=url,timeout=1)
这个方法还能够拿来检测代理 ip 的质量,如果一个代理 ip 在很长时间没有响应,那么添加超时之后也会报错,对用的ip就可以从代理 ip池中删除。
13. retrying模块的使用
使用超时参数能够加快我们整体的运行速度。但是在普通的生活中当我们使用浏览器访问网页时,如果发生速度很慢的情况,我们会做的选择时刷新页面。那么在代码中,我们是否也可以刷新请求呢?
在这我们使用 retrying 模块来完成需求。
retrying 模块的使用:
模块地址:https://pypi.org/project/retrying/
# 安装指令如下:
pip install retrying -i https://pypi.tuna.tsinghua.edu.cn/simple
作用:
- 使用 retrying 模块提供的 retry 模块
- 通过装饰器的方式使用,让被装饰的函数反复执行
- retry 中可以传入参数 stop_max_attempt_number,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行。
import time
from retrying import retry
num=1
@retry(stop_max_attempt_number=3)
def test():
global num
print("num=",num)
num+=1
time.sleep(1)
for i in 100:
print("i",i)
if __name__=="__main__":
try:
test()
except Exception as ret:
print("产生异常...")
print(ret)
else:
print("没有异常")
示例代码:
import requests
from retrying import retry
num=1
@retry(stop_max_attempt_number=3)
def _parse_url(url):
global num
print("第%d次尝试" % num)
num+=1
headers={}
# 超时的时候会报错并重试
response=requests.get(url,headers=headers,timeout=3)
# 状态码不是200,也会报错并重试
assert response.status_code==200 # 此语句是"断言",如果assert后面的条件为True则呈现继续运行,否则抛出异常
return response
def parse_url(url):
# 进行异常捕获
try:
response=_parse_url(url)
except Exception as e:
print('产生异常:',e)
response=None
return response
if __name__=='__main__':
url="https://chinasoftinc.com/owa"
print("---开始---")
res=parse_url(url=url)
print("-----结束-----","响应内容为:",res)
14. 发送json格式数据
当我们发生 POST 请求的时候,一般会携带数据,之前在学习POST 时,可以通过给 data 赋值,从而能够完成传递 form 表单数据。
requests.post(url, data={"kw": "python"})
但有很多时候,要向服务器发送的是 json 数据,此时应该怎么办呢?
requests.post(url, json={"kw": "python"})
在请求方法中设置 json 参数即可。
代码示例:
import requests
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
}
response = requests.post("https://fanyi.baidu.com/sug", headers=headers, json={"kw": "python"}, timeout=3)
print("请求头是:", response.request.headers)
print("请求体是:", response.request.body)
15.session会话
当我们在爬取某些页面的时候,服务器往往会需要cookie,而想要得到 cookie 就需要先访问某个 URL 进行登录,服务器接收到请求之后验证用户名以及密码在登录成功的情况下会返回一个响应,这个响应的 header 中要一般会有一个 set-cookie 的信息,它对应的值就是要设置的 cookie信息。
虽然之前可以通过 requests.utils.dict_from_cookiejar(res.cookies) 提取到这个响应信息中设置的新 cookie,但在下一个请求中再携带这个数据的过程较为麻烦,所以 requests 有个高级的方式 - 会话 Session
Session的作用:
Session能够跨请求保持某些参数,也会在同一个Session实例发出的所有请求之间保持 cookie
会话保持有两个内涵:
- 保存 cookie,下一次请求会自动带上前一次的cookie
- 实现和服务端的长连接,加快请求速度
使用方法:
# 创建一个session实例对象
s=requests.Session()
# 使用上一步创建的对象发起请求
r=s.get(url1,headers)
r=s.get(url2,headers)
r=s.get(url3,headers)
r=s.get(url4,headers)
session 对象在请求了一个网站后,对方服务器设置在本地的cookie会保存在session对象中,下一次再使用session对象请求对方服务器的时候,会自动带上前一次的cookie。
代码示例:
import requests
session = requests.Session()
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
}
# 发送第一个请求
response = session.get('https://www.baidu.com', headers=headers)
print("第一次请求的请求头为:", response.request.headers)
print("响应头:", response.headers)
print("设置的cookie为:", requests.utils.dict_from_cookiejar(response.cookies))
# 发送第二个请求
response = session.get("https://www.baidu.com")
print("第二次请求的请求头为:", response.request.headers)
16. 代理
使用代理的原因:
当在爬某个网站的时候,如果对方进行了封锁,例如将我们电脑的公网ip封锁了,那么也就意味着只要是这个 ip 发送的所有请求这个网站都不会进行响应;此时我们就可以使用代理,绕过它的封锁从而实现继续爬取数据。
基本原理:
在当前用户电脑中连接其他区域的电脑,每台电脑因为区域不同所以分配的 ip 也不相同。使用其他区域的电脑帮助我们发送想要发送的请求。
基本使用:
将代理地址与端口配置成字典并使用 proxies参数传递
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
requests.get("https://example.org", proxies=proxies)
如何获取代理
- 百度查询 免费代理ip,但一般情况下都不太好用
- 付费代理: https://www.zmhttp.com/?have_open_ok=1
对于免费代理大部分都是不可用的,建议可以使用付费代理。例如:芝麻代理、快代理等等。
import requests
# http代理
ip = "127.0.0.1"
port = 7890
proxies = {
"http": "http://%s:%d" % (ip, port),
"https": "http://%s:%d" % (ip, port)
}
# 请求头
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36"
}
url = "http://httpbin.org/ip"
response = requests.get(url=url, headers=headers, proxies=proxies, timeout=10)
print(response.text)