每天进步一点点:如何python requests 中使用代理

Words
1148
Reading
6 min
Listen
Play
9M

之前给大家介绍过我的简易见证人监控报警器,然后又给大家介绍了如何通过Python给自己的TG账户发送消息,这样见证人丢块时不但能听到蜂鸣器报警,还可以在TG中看到通知。

image.png
(图源 :pixabay)

但是,上述两个方案有一个很严重的问题:就是如果都部署在远程服务器上,就没法听到报警器响(好吧,我也没法去国外机房部署报警器);而部署在家里呢,就没法给TG账户发消息(原因嘛,懂得都懂)。

前两天为了解决git clone等操作网速超慢的问题,我折腾了一番我的内网专用socks代理机 ,不但大幅提升这些操作的速度,稳定性也得到了保证。

于是我又想,是否可以在这个基础上解决Python本地发送通知给TG的问题呢?

如果可以解决,那么蜂鸣器报警器+Telegram通知就可以集成到一套程序中,部署在家里的香蕉派或者树莓派上就可以搞定了!岂不是相当优雅?

然后我突然就想到了解决方案,因为这和我在主机工作账户下使用git clone是一个道理呀!解决方案就是导入如下环境变量:

export http_proxy=socks5h://ip:port
export https_proxy=$http_proxy

这时账户下的http和https流量就都自动走代理啦。让我用之前的发消息代码测试一下,结果出现如下提示:

raise InvalidSchema("Missing dependencies for SOCKS support.")
requests.exceptions.InvalidSchema: Missing dependencies for SOCKS support.

看来事情没我想象的那么简单呀?但是貌似也不难,解决方法很简单,执行如下指令即可:

pip install requests[socks] 或者pip install pysocks

再次测试,收到消息,搞定!

44e64fba29f54ebb6f727428b58e8da1.png

不过等等,现在又出现了一个新问题,为了降低HIVE公共API节点的压力,我让我的脚本访问我局域网内的HIVE节点。但若是加上以上代理设置,岂不是我访问局域网也要走socks代理了?那样岂不是无法访问局域网节点了?

测试了一下,果然如此,看来事情没我想象的那么简单呀!

不过貌似也不难,那就是设置no_proxy环境变量。比如:

export no_proxy=localhost,127.0.0.1,::1,192.168.0.0/16

测试一下,一切OK。

现在问题貌似完美解决,我即可以通过socks代理访问指定的网址,又不影响我本地或者局域网流量不走socks代理,似乎可以告一段落了。

但是我又想到一个新问题,假设我想访问两个外网网址,一个走代理,一个不走代理,我岂不是还要修改no_proxy环境变量?

另外,我总是觉得设置环境变量的方式很不优雅,比如登录后我要设置环境(或者放.bashrc),那么如果我想用crontab调用脚本,上述环境变量还会生效嘛?

答案是crontab调用脚本,环境变量不生效

解决方法也不是没有,比如在 crontab 中直接写环境变量

http_proxy=socks5h://ip:port
https_proxy=socks5h://ip:port
no_proxy=localhost,127.0.0.1,::1,192.168.0.0/16

*/10 * * * * /path/to/script.sh

又或者在Python脚本中设置环境变量(对当前进程与子进程有效):

import os

os.environ["http_proxy"] = "socks5h://ip:port"
os.environ["https_proxy"] = os.environ["http_proxy"]
os.environ["no_proxy"] = "localhost,127.0.0.1,::1,192.168.0.0/16"

这些都能解决问题,那么有没有更直接的方案呢?

经过我一番探索和尝试,我们可以直接在Python代码中使用如下方式让访问通过代理或不走代理:

proxies = {
    "http": "socks5h://ip:port",
    "https": "socks5h://ip:port",
}

response = requests.post(url, data=payload, proxies=proxies, timeout=5)
#response = requests.post(url, data=payload, timeout=5)

如果我们

我觉得最后一种方案,完美地解决了我的问题,且最直观,最容易理解。所以就用它啦!
social-3408791_960_720.webp
(图源 :pixabay)

至此,问题完全解决!所以,我就可以把报警器完美集成上TG通知功能喽。这才是我想要的完美报警器呀!😍

相关链接