Skip to content

1.Requests模块的使用

requests模块的介绍与安装

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

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

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

模块安装

安装命令:

txt
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向百度首页发送请求,获取百度首页数据

python
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("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

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

python
import requests

r = 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响应内容写入文件内
python
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

python
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. 显示视频下载进度
python
import requests

# 视频URL
video_url = "https://v95-bj.douyinvod.com/74d5493171db92a4046a588dde55a9c9/651fbbe5/video/tos/cn/tos-cn-ve-15c001-alinc2/o4NBwAtAz6knVLKFgeq9ZpbDAuAeECDkgQUIsc/?a=1128&ch=0&cr=0&dr=0&er=0&cd=0%7C0%7C0%7C0&cv=1&br=2296&bt=2296&cs=0&ds=4&ft=blh3-IQQqU-mfJ4ZPo0OW_EklpPiX9f22FVJEad.trbPD-I&mime_type=video_mp4&qs=0&rc=NzYzPDY8ZGlkO2U3NWhoZ0BpM3E8dzg6ZnR0bTMzNGkzM0BeNTU0XmNfNTIxX2MtXi4tYSMyYGovcjRfLi5gLS1kLWFzcw%3D%3D&btag=e000a8000&dy_q=1696574824&l=20231006144704E736E605E5E7C30F951B"

# 发送请求
r = requests.get(url=video_url, stream=True)

response_body_length = int(r.headers.get("Content-Length"))
# print("body的数据长度为:", response_body_length)

# 获取响应内容存储到文件
with open("抖音.mp4", 'wb') as fd:
    write_length = 0
    for chunk in r.iter_content(chunk_size=100):
        write_length += fd.write(chunk)  # write的返回值为写入到文件内容的多少
        print("下载进度: %02.2f%%" % (100 * write_length / response_body_length))
发送请求时需要携带请求头

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

获取请求头与响应头

python
import requests

r = requests.get("https://www.baidu.com")

print(r.headers)  # 响应头
print(r.request.headers)  # 请求头

添加User-Agent

python
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请求百度

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/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

python
# 1. 设置需要携带的查询字符串参数
kw = {'wd': 'java'}

# 2. 发送请求
response = requests.get('https://www.baidu.com/s', params=kw)

# 3.查看发送的URL
print(response.url)

当前查询字符串参数可以直接写到url地址中:

python
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)
使用requests发送post请求

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

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

发送post请求

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

发送post请求代码示例:

python
# 网站首页:http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice#szse
# api地址:http://www.cninfo.com.cn/new/disclosure

import 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请求
代码练习:百度翻译
python
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
python
# 将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参数接收
python
cookie_dict = {"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对象转化为字典
python
import requests

url = "https://www.baidu.com"
# 发送请求,获取resposne
response = requests.get(url)
print(type(response.cookies))

# 使用方法从cookiejar中提取数据
cookies = requests.utils.dict_from_cookiejar(response.cookies)
print(cookies)
重定向与历史请求

测试代码

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

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

取消自动重定向

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

python
requests.get(url, allow_redirects=False)

示例代码:

python
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, allow_redirects=False)

print(r.status_code)
print(r.url)

默认情况下获取历史请求

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

python
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.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的证书不安全导致。

在代码中发起请求的效果

python
import requests

url = "https://chinasoftinc.com/owa"
response = requests.get(url)


# 当前程序报错:ssl.CertificateError...

解决方案

在代码中设置verify参数

python
import requests

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

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

超时参数的使用

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

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

python
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/

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

作用:

  1. 使用retrying模块提供的retry模块
  2. 通过装饰器的方式使用,让被装饰的函数反复执行
  3. retry中可以传入参数stop_max_attempt_number,让函数报错后继续重新执行,达到最大执行次数的上限,如果每次都报错,整个函数报错,如果中间有一个成功,程序继续往后执行
python
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("没有异常")

retryingrequests的简单封装

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

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

示例代码:

python
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 = {
        "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 response


def parse_url(url):
    # 进行异常捕获
    try:
        response = _parse_url(url)
    except Exception as e:
        print("产生异常:", e)
        # 报错返回None
        response = None
    return response


if __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表单数据。

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

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

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

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

代码示例:

python
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.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
  • 实现和服务端的长连接,加快请求速度

使用方法

python
# 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

代码示例:

python
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)
代理

使用代理的原因

当在爬某个网站的时候,如果对方进行了封锁例如将我们电脑的公网ip封锁了,那么也就意味着只要是这个ip发送的所有请求这个网站都不会进行响应;此时我们就可以使用代理,绕过它的封锁从而实现继续爬取数据

基本原理

在当前用户电脑中连接其他区域的电脑,每台电脑因为区域不同所以分配的ip也不相同。使用其他区域的电脑帮助我们发送想要发送的请求。

基本使用

将代理地址与端口配置成字典并使用proxies参数传递

python
proxies = {
  "http": "http://10.10.1.10:3128",
  "https": "http://10.10.1.10:1080",
}

requests.get("https://example.org", proxies=proxies)

如何获取代理

对于免费代理大部分都是不可用的,建议可以使用付费代理。例如:芝麻代理、快代理等等。

代理案例

python
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)

Sube's Study Notes.