python爬虫基础:requests库详解与案例

1.Requests模块的使用

requests模块的介绍与安装

作用:发送网络请求,返回响应数据。

中文文档:https://requests.readthedocs.io/projects/cn/zh_CN/latest/

对于爬虫任务,使用 requests模块基本能够解决绝大部分的数据抓取的任务。所以用好 requests至关重要

模块安装

安装命令:

pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
requests功能特性
  • Keep-Alive & 连接池
  • 国际化域名和 URL
  • 带持久 Cookie的会话
  • 浏览器式的 SSL认证
  • 自动内容解码
  • 基本/摘要式的身份认证
  • 优雅的 key/value Cookie
  • 自动解压
  • Unicode响应体
  • HTTP(S)代理支持
  • 文件分块上传
  • 流下载
  • 连接超时
  • 分块请求=-
  • 支持 .netrc
requests发送网络请求以及常用属性

需求:通过 requests向百度首页发送请求,获取百度首页数据

import requestsurl = "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("utf-8"))

常用属性如下:

  • 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
textcontent方法区别
  • response.text
    • 类型:str
    • 解码类型:requests模块根据 HTTP头部对响应的编码推测文本编码类型
    • 修改编码方式:response.encoding = 'gbk'
  • response.content
    • 类型:bytes
    • 解码类型:没有指定
    • 修改编码方式:response.content.decode('utf-8')

获取网页源码的通用方式:

  1. response.encoding = 'utf-8'
  2. response.content.decode('utf-8')
  3. response.text

以上三种方式从前往后依次尝试,百分百可以解决网页编码问题。

import requestsr = requests.get("https://www.baidu.com")print("-----requests一般能够根据响应自动解码-----")
print(r.text)print("-----如果不能够解析出想要的真实数据,可以通过设置解码方式-----")
r.encoding = "utf-8"
print(r.text)
下载网络图片

需求:将百度 logo下载到本地

思路分析:

  1. logourl地址:https://www.baidu.com/img/bd_logo1.png
  2. 利用 requests模块发送请求并获取响应
  3. 使用二进制写入的方式打开文件并将 response响应内容写入文件内
import requests# 图片的url
url = 'https://ywww.baidu.com/img/bd_logo1.png'# 响应本身就是一个图片,并且是二进制类型
r = requests.get(url)# print(r.content)# 以二进制+写入的方式打开文件
with open('baidu.png', 'wb') as f:# r.content bytes二进制类型f.write(r.content)
iter_content方法

如果下载一个较大的资源,例如一个视频,可能需要的下载时间较长,在这个较长的下载过程中程序是不能做别的事情的(当然可以使用多任务来解决),如果在不是多任务的情况下,想要知道下载的进度,此时就可以通过类似迭代的方式下载部分资源。

  1. 使用 iter_content

在获取数据时,设置属性 stream=True

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)
  1. stream=True说明
  • 如果设置了 stream=True,那么在调用 iter_content方法时才会真正下载内容
  • 如果没设置 stream属性则调用 requests.get就会耗费时间下载
  1. 显示视频下载进度
import requestsdef download_video(url, save_path):response = requests.get(url, stream=True)total_size = int(response.headers.get('content-length', 0))downloaded_size = 0with open(save_path, 'wb') as file:for chunk in response.iter_content(chunk_size=1024):if chunk:file.write(chunk)downloaded_size += len(chunk)percent = (downloaded_size / total_size) * 100print(f"下载进度: {percent:.2f}%")print("下载完成...")# 调用下载函数
video_url = "http://v3-web.douyinvod.com/dbb2c985b18e9a2b6089ada19767525f/659692f3/video/tos/cn/tos-cn-ve-15c001-alinc2/oQblva95AUnIpA9DeieFkQmqAIu0IgBVD2iNTA/?a=6383&ch=5&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=1161&bt=1161&cs=0&ds=4&ft=LjhJEL998xIouEkmD0P5H4eaciDXtVzxF_QEePMkzijD1Inz&mime_type=video_mp4&qs=0&rc=NTYzOGVlZmZpaDo6M2loM0BpM3VseGQ6ZnM2bjMzNGkzM0BgYDQuXi5iNS8xXmBgMDNfYSMvbmZocjQwL2RgLS1kLWFzcw%3D%3D&btag=e00038000&dy_q=1704362620&feature_id=46a7bb47b4fd1280f3d3825bf2b29388&l=202401041803391CCB1AB5D5A9E107FA68"
path = "video.mp4"
download_video(video_url, path)
发送请求时需要携带请求头

在请求某些网址时根据不同的浏览器会返回不同的响应内容,所以此时就需要根据需求来修改或添加请求头信息

获取请求头与响应头

import requestsr = requests.get("https://www.baidu.com")print(r.headers)  # 响应头
print(r.request.headers)  # 请求头

添加 User-Agent

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"}requests.get(url, headers=headers)

携带 User-Agent请求百度

import requestsurl = 'https://www.baidu.com'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"
}# 在请求头中带上User-Agent,模拟浏览器发送请求
# r = requests.get(url)
r = requests.get(url, headers=headers)# 打印请求头信息
print(r.request.headers)# 响应内容
print(r.text)
发送带有 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 requestsheaders = {"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)
使用 requests发送 post请求

HTTP请求中,GETPOST是使用最为频繁的请求方式。

  • GET:获取数据
  • POST:提交数据

发送 post请求

requests模块中能发送多种请求,例如:GETPOSTPUTDELETE等等

发送 post请求代码示例:

# 网站首页:http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice#szse
# api地址:http://www.cninfo.com.cn/new/disclosureimport requests# 获取到url
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/104.0.0.0 Safari/537.36'
}
data = {'column':'szse_latest','pageNum':'2','pageSize':'30','sortName':'','sortType':'','clusterFlag':'true',
}response = requests.post(url, headers=headers, data=data)
print(response.json())

过程分析:

  1. 通过浏览器开发者工具获取当前网站数据 API
  2. 查询载荷选项卡中的表单数据
  3. 构建表单数据
  4. 发送 post请求
代码练习:百度翻译
import requests# 当前请求的地址为移动端地址
url = 'https://fanyi.baidu.com/basetrans'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=='
}post_data = {'query': 'happy','from': 'en','to': 'zh','token': '5ff0092d623c21bdb9b429187512af44','sign': '221212.492333'
}response = requests.post(url, headers=headers, data=post_data).json()
print(response['trans'][0]['dst'])

注意:当前示例中的 cookie参数与表单参数需要自行获取。

requests处理 cookie

引入

为了能够通过爬虫获取到登录后的页面,或者是解决通过 cookie的反爬,需要使用 request来处理 cookie相关的请求。

爬虫中使用 cookie的利弊

  1. 带上 cookie的好处
    • 能够访问登录后的页面
    • 能够实现部分反反爬
  2. 带上 cookie的坏处
    • 一套 cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫
    • 那么上面的问题如何解决?使用多个账号

发送请求时添加 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表示键 nameb表示值 value
  • headers中仅仅使用了 cookienamevalue
  1. cookie字典传给请求方法的 cookies参数接收
cookies = {"cookie的name": "cookie的value"}requests.get(url, headers=headers, cookies=cookie_dict)
  1. 使用 requests提供的 session模块(后面讲解)

获取响应时提取 cookie

使用 requests获取的 resposne对象,具有 cookies属性,能够获取对方服务器设置在本地的 cookie,但是如何使用这些 cookie呢?

使用 requests模块提供的 response.cookies方法。

  • response.cookiesCookieJar类型
  • 使用 requests.utils.dict_from_cookiejar,能够实现把 cookiejar对象转化为字典
import requestsurl = "https://www.baidu.com"
# 发送请求,获取resposne
response = requests.get(url)
print(type(response.cookies))# 使用方法从cookiejar中提取数据
cookies = requests.utils.dict_from_cookiejar(response.cookies)
print(cookies)
重定向与历史请求

测试代码

import requestsheaders = {"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之外,其余的请求例如 GETPOST等都是能自动进行重定向的

这也就是为什么上面明明访问的是 http://www.baidu.com而打印出来之后是 https://m.baidu.com/?from=844b&vit=fps的原因

取消自动重定向

在发送请求的时候,可以通过如下的设置,取消 requests模块的自动重定向功能

requests.get(url, allow_redirects=False)

示例代码:

import requestsheaders = {"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, allow_redirects=False)print(r.status_code)
print(r.url)

默认情况下获取历史请求

通过 response.history可以获取到请求的历史记录

import requestsheaders = {"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.360buy.com", headers=headers)print("历史请求过程信息:")
print(r.history)
for one_info in r.history:print(one_info.status_code, one_info.url, one_info.headers)print("\n\n最后一次的请求信息:")
print(r.status_code, r.url, r.headers)
SSL证书错误

在浏览网页时,可能会遇到以下这种情况:

出现这个问题的原因是:ssl的证书不安全导致。

在代码中发起请求的效果

import requestsurl = "https://chinasoftinc.com/owa"
response = requests.get(url)# 当前程序报错:ssl.CertificateError...

解决方案

在代码中设置 verify参数

import requestsurl = "https://12306.cn/mormhweb/"
response = requests.get(url, verify=False)
请求超时

在爬虫中,一个请求很久没有结果,就会让整个项目的效率变得非常低。这个时候我们就需要对请求进行强制要求,让他必须在特定的时间内返回结果,否则就报错。

超时参数的使用

r = requests.get(url, timeout=3)

通过添加 timeout参数,能够保证在3秒钟内返回响应,否则会报错。

import requests# url = "https://www.baidu.com"
url = "https://www.google.com"response = requests.get(url=url, timeout=1)

这个方法还能够拿来检测代理 ip(代理会在后面讲解)的质量,如果一个代理 ip在很长时间没有响应,那么添加超时之后也会报错,对应的这个 ip就可以从代理 ip池中删除。

retrying模块的使用

使用超时参数能够加快我们整体的运行速度。但是在普通的生活中当我们使用浏览器访问网页时,如果发生速度很慢的情况,我们会做的选择是刷新页面。那么在代码中,我们是否也可以刷新请求呢?

在本小节中我们使用 retrying模块来完成需求。

retrying模块的使用

模块地址:https://pypi.org/project/retrying/

安装指令如下:pip install retrying -i https://pypi.tuna.tsinghua.edu.cn/simple

作用:

  1. 使用 retrying模块提供的 retry模块
  2. 通过装饰器的方式使用,让被装饰的函数反复执行
  3. retry中可以传入参数 stop_max_attempt_number,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行
import timefrom retrying import retrynum = 1@retry(stop_max_attempt_number=3)
def test():global numprint("num=", num)num += 1time.sleep(1)for i in 100:print("i", i)if __name__ == '__main__':try:test()except Exception as ret:print("产生异常...")print(ret)else:print("没有异常")

retryingrequests的简单封装

实现一个发送请求的函数,每次爬虫中直接调用该函数即可实现发送请求

  • 使用 timeout实现超时报错
  • 使用 retrying模块实现重试

示例代码:

import requests
from retrying import retrynum = 1@retry(stop_max_attempt_number=3)
def _parse_url(url):global numprint("第%d次尝试" % num)num += 1headers = {"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.get(url, headers=headers, timeout=3)# 状态码不是200,也会报错并重试assert response.status_code == 200  # 此语句是"断言",如果assert后面的条件为True则呈现继续运行,否则抛出异常return responsedef parse_url(url):# 进行异常捕获try:response = _parse_url(url)except Exception as e:print("产生异常:", e)# 报错返回Noneresponse = Nonereturn responseif __name__ == '__main__':url = "https://chinasoftinc.com/owa"# url = "https://www.baidu.com"print("----开始----")r = parse_url(url=url)print("----结束----", "响应内容为:", r)
发送 json格式数据

当我们发送 POST请求的时候,一般会携带数据,之前在学习 POST时,可以通过给 data赋值,从而能够完成传递 form表单数据。

requests.post(url, data={"kw": "python"})

但有很多时候,要向服务器发送的是 json数据,此时应该怎么办呢?

requests.post(url, json={"kw": "python"})

在请求方法中设置 json参数即可。

代码示例:

import requestsheaders = {"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.post("https://fanyi.baidu.com/sug", headers=headers, json={"kw": "python"}, timeout=3)
print("请求头是:", r.request.headers)
print("请求体是:", r.request.body)
Session会话

当我们在爬取某些页面的时候,服务器往往会需要 cookie,而想要得到 cookie就需要先访问某个 URL进行登录,服务器接收到请求之后验证用户名以及密码在登录成功的情况下会返回一个响应,这个响应的 header中一般会有一个 set-cookie的信息,它对应的值就是要设置的 cookie信息。

虽然我们再之前可以通过 requests.utils.dict_from_cookiejar(r.cookies)提取到这个响应信息中设置的新 cookie,但在下一个请求中再携带这个数据的过程较为麻烦,所以 requests有个高级的方式 - 会话 Session

Session的作用

Session能够跨请求保持某些参数,也会在同一个 Session实例发出的所有请求之间保持 cookie

会话保持有两个内涵:

  • 保存 cookie,下一次请求会自动带上前一次的 cookie
  • 实现和服务端的长连接,加快请求速度

使用方法

# 1. 创建一个session实例对象
s = requests.Session()# 2. 使用上一步创建的对象发起请求
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 requestssession = 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)
代理

使用代理的原因

当在爬某个网站的时候,如果对方进行了封锁例如将我们电脑的公网 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 = 7890proxies = {"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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring 容器相关的核心注解​

以下是 Spring 容器中用于 ​​Bean 管理、依赖注入、配置控制​​ 的关键注解,按功能分类说明: ​​1. Bean 声明与注册​​ 注解作用示例​​Component​​通用注解,标记一个类为 Spring Bean(自动扫描注册) Compo…

C与指针5——字符串合集

常用函数 1、拷贝、长度、比较 size_t strlen();\\返回无符号整形 char* strcpy();char* strncpy();\\拷贝 int strcmp();int strncmp();\\比较 char* strcat();char* strncat();\\连接2、查找 char* strchr(const char * st,int ch);\\找字符第一次出现的位置 char* strrch…

论软件需求管理

目录 摘要(300~330字) 正文(2000~2500字,2200字为宜) 背景介绍(500字做左右) 论点论据(1500字做左右) 收尾(200字左右) 注:本篇论…

[特殊字符] 如何在比赛前调整到最佳状态:科学与策略结合的优化指

🧠 概述 在竞技体育中,赛前状态的调整对比赛结果起着决定性作用。所谓“最佳状态”,不仅指生理上的巅峰表现,更包括心理、认知、营养和恢复等多方面的协同优化。本文结合运动科学、心理学和营养学的研究成果,探讨赛前…

一种实波束前视扫描雷达目标二维定位方法——论文阅读

一种实波束前视扫描雷达目标二维定位方法 1. 专利的研究目标与实际问题意义2. 专利提出的新方法、模型与公式2.1 运动平台几何建模与回波信号构建2.1.1 距离历史建模2.1.2 回波信号模型2.2 距离向运动补偿技术2.2.1 匹配滤波与距离压缩2.3 加权最小二乘目标函数2.3.1 方位向信号…

基于 Spring Boot 瑞吉外卖系统开发(八)

基于 Spring Boot 瑞吉外卖系统开发(八) 自动填充公共字段 MyBatis-Plus公共字段自动填充,也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,降低了冗余代码的数量。本…

【前端】从零开始的搭建结构(技术栈:Node.js + Express + MongoDB + React)book-management

项目路径总结 后端结构 server/ ├── controllers/ # 业务逻辑 │ ├── authController.js │ ├── bookController.js │ ├── genreController.js │ └── userController.js ├── middleware/ # 中间件 │ ├── authMiddleware…

【RAG】向量?知识库的底层原理:向量数据库の技术鉴赏 | HNSW(导航小世界)、LSH、K-means

一、向量化表示的核心概念 1.1 特征空间与向量表示 多维特征表示:通过多个特征维度(如体型、毛发长度、鼻子长短等)描述对象,每个对象对应高维空间中的一个坐标点,来表示狗这个对象,这样可以区分出不同种…

如何用CSS实现HTML元素的旋转效果

原文:如何用CSS实现HTML元素的旋转效果 | w3cschool笔记 (本文为科普文章,请勿标记为付费) 在网页制作中,为 HTML 元素设置旋转效果可使其更灵动,提升用户体验。本文将深入浅出地介绍如何利用 CSS 实现 H…

Spark集群搭建之Yarn模式

配置集群 1.上传并解压spark-3.1.2-bin-hadoop3.2.tgz,重命名解压之后的目录为spark-yarn。 2. 修改一下spark的环境变量,/etc/profile.d/my_env.sh 。 # spark 环境变量 export SPARK_HOME/opt/module/spark-yarn export PATH$PATH:$SPARK_HOME/bin:$SP…

xLua笔记

Generate Code干了什么 肉眼可见的,在Asset文件夹生成了XLua/Gen文件夹,里面有一些脚本。然后对加了[CSharpCallLua]的变量寻找引用,发现它被XLua/Gen/DelegatesGensBridge引用了。也可以在这里查哪些类型加了[CSharpCallLua]。 public over…

【tcp连接windows redis】

tcp连接windows redis 修改redis.conf 修改redis.conf bind * -::*表示禁用保护模式,允许外部网络连接 protected-mode no

【序列贪心】摆动序列 / 最长递增子序列 / 递增的三元子序列 / 最长连续递增序列

⭐️个人主页:小羊 ⭐️所属专栏:贪心算法 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 摆动序列最长递增子序列递增的三元子序列最长连续递增序列 摆动序列 摆动序列 贪心策略:统计出所有的极大值和极小…

STM32F103C8T6使用MLX90614模块

首先说明: 1.SMBus和I2C的区别 我曾尝试用江科大的I2C底层去直接读取该模块,但是无法成功,之后AI生成的的代码也无法成功。 思来想去最大的可能就是SMBus这个协议的问题,根据百度得到的结果如下: SMBus和I2C的区别 链…

tp5 php获取农历年月日干支甲午

# 切换为国内镜像源 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/# 再次尝试安装 composer require overtrue/chinese-calendar核心写法一个农历转公历,一个公历转农历 农历闰月可能被错误标记(例如 闰四月 应表示…

Ubuntu搭建Conda+Python开发环境

目录 一、环境说明 1、测试环境为ubuntu24.04.1 2、更新系统环境 3、安装wget工具 4、下载miniconda安装脚本 二、安装步骤 1、安装miniconda 2、source conda 3、验证版本 4、配置pip源 三、conda用法 1、常用指令 一、环境说明 1、测试环境为ubuntu24.04.1 2、更…

Vscode+git笔记

1.U是untracked m是modify modified修改了的。 2.check out 查看观察 3 status changed 暂存区 4.fetch v 取来拿来 5.orangion 起源代表远程分支 git checkout就是可以理解为进入的意思。

模拟SIP终端向Freeswitch注册用户

1、简介 使用go语言编写一个程序,模拟SIP-T58终端在Freeswitch上注册用户 2、思路 以客户端向服务端Freeswitch发起REGISTER请求,告知服务器当前的联系地址构造SIP REGISTER请求 创建UDP连接,连接到Freeswitch的5060端口发送初始的REGISTER请…

DeepSeek实战--LLM微调

1.为什么是微调 ? 微调LLM(Fine-tuning Large Language Models) 是指基于预训练好的大型语言模型(如GPT、LLaMA、PaLM等),通过特定领域或任务的数据进一步训练,使其适应具体需求的过程。它是将…

Docker与WSL2如何清理

文章目录 Docker与WSL2如何清理一、docker占据磁盘空间核心原因分析1. WSL2 虚拟磁盘的动态扩展特性2. Docker 镜像分层缓存与未清理资源 二、解决方案步骤 1:清理 Docker 未使用的资源步骤 2:手动压缩 WSL2 虚拟磁盘1. 关闭 WSL2 和 Docker Desktop2. 定…