带有 Python 和 urllib2 的源接口 [英] Source interface with Python and urllib2

查看:32
本文介绍了带有 Python 和 urllib2 的源接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 Python 和 urllib2 设置源 IP/接口?

How do i set the source IP/interface with Python and urllib2?

推荐答案

不幸的是,正在使用的标准库模块堆栈(urllib2、httplib、socket)的设计有些糟糕——在操作的关键点,HTTPConnection.connect(在 httplib 中)委托给 socket.create_connection,这反过来在创建套接字实例 socksock.connect 调用,以便您在 sock.connect 之前插入 sock.bind 这是您需要设置的源 IP(我正在广泛宣传,因为我没有以如此密闭、过度封装的方式设计抽象——我将在本周四的 OSCON 上以禅与抽象维护的艺术"为标题谈论这一点——但是这里你的问题是如何处理一堆以这种方式设计的抽象,叹息).

Unfortunately the stack of standard library modules in use (urllib2, httplib, socket) is somewhat badly designed for the purpose -- at the key point in the operation, HTTPConnection.connect (in httplib) delegates to socket.create_connection, which in turn gives you no "hook" whatsoever between the creation of the socket instance sock and the sock.connect call, for you to insert the sock.bind just before sock.connect that is what you need to set the source IP (I'm evangelizing widely for NOT designing abstractions in such an airtight, excessively-encapsulated way -- I'll be speaking about that at OSCON this Thursday under the title "Zen and the Art of Abstraction Maintenance" -- but here your problem is how to deal with a stack of abstractions that WERE designed this way, sigh).

当您遇到此类问题时,您只有两个不太好的解决方案:复制、粘贴和编辑错误设计的代码,您需要在其中放置一个原始设计人员不适合的钩子";或者,猴子补丁"该代码.两者都不好,但两者都可以工作,所以至少让我们感谢我们有这样的选择(通过使用开源和动态语言).在这种情况下,我想我会使用猴子补丁(这很糟糕,但复制和粘贴编码更糟糕)——一个代码片段,例如:

When you're facing such problems you only have two not-so-good solutions: either copy, paste and edit the misdesigned code into which you need to place a "hook" that the original designer didn't cater for; or, "monkey-patch" that code. Neither is GOOD, but both can work, so at least let's be thankful that we have such options (by using an open-source and dynamic language). In this case, I think I'd go for monkey-patching (which is bad, but copy and paste coding is even worse) -- a code fragment such as:

import socket
true_socket = socket.socket
def bound_socket(*a, **k):
    sock = true_socket(*a, **k)
    sock.bind((sourceIP, 0))
    return sock
socket.socket = bound_socket

根据您的确切需求(您是否需要将所有套接字都绑定到相同的源 IP,或者...?)您可以在正常使用 urllib2 之前简单地运行它,或者(在更多复杂的方式当然)只为那些你需要以某种方式绑定的传出套接字运行它(然后每次恢复 socket.socket = true_socket 为未来的套接字让路来创建).第二种选择增加了它自己的复杂性以正确编排,所以在解释所有这些复杂性之前,我在等你澄清你是否确实需要这些复杂性.

Depending on your exact needs (do you need all sockets to be bound to the same source IP, or...?) you could simply run this before using urllib2 normally, or (in more complex ways of course) run it at need just for those outgoing sockets you DO need to bind in a certain way (then each time restore socket.socket = true_socket to get out of the way for future sockets yet to be created). The second alternative adds its own complications to orchestrate properly, so I'm waiting for you to clarify whether you do need such complications before explaining them all.

AKX 的好答案是复制/粘贴/编辑"替代方案的一个变体,所以我不需要对此进行太多扩展——但请注意,它并没有完全重现 socket.create_connection 在其 connect 方法中,请参阅源代码 此处(在页面的最后)并决定您可能希望在复制/粘贴/编辑版本中包含 create_connection 函数的哪些其他功能如果你决定走那条路.

AKX's good answer is a variant on the "copy / paste / edit" alternative so I don't need to expand much on that -- note however that it doesn't exactly reproduce socket.create_connection in its connect method, see the source here (at the very end of the page) and decide what other functionality of the create_connection function you may want to embody in your copied/pasted/edited version if you decide to go that route.

这篇关于带有 Python 和 urllib2 的源接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆