मैं पाइथन और urllib2 के साथ स्रोत आईपी/इंटरफ़ेस कैसे सेट करूं?पाइथन और urllib2 के साथ स्रोत इंटरफेस
उत्तर
दुर्भाग्य से उपयोग में मानक पुस्तकालय मॉड्यूल के ढेर (urllib2, httplib, सॉकेट) कुछ हद तक बुरी तरह से इस प्रयोजन के लिए डिज़ाइन किया गया है आप कोई "हुक" जो भी सॉकेट उदाहरण sock
के सृजन और sock.connect
कॉल के बीच, आप सम्मिलित करना के लिए sock.bind
बस से पहले sock.connect
है कि आप स्रोत आईपी (मैं नहीं इस तरह में कपोल-कल्पना डिजाइन करने के लिए व्यापक रूप से प्रचार कर रहा हूँ निर्धारित करने की आवश्यकता क्या एक वायुरोधी, अत्यधिक-encapsulated तरीका - मैं इसके बारे में ओएसकॉन में "जेन और आर्ट ऑफ एब्स्ट्रक्शन रखरखाव" शीर्षक के तहत इस बारे में बात करूँगा - लेकिन यहां आपकी समस्या यह है कि कैसे डिजाइन किया गया है अबाउट के ढेर से निपटने के लिए इस तरह, श्वास)।
जब आपको ऐसी समस्याएं आ रही हैं तो आपके पास केवल दो अच्छे समाधान नहीं हैं: या तो गलत डिज़ाइन किए गए कोड को कॉपी, पेस्ट और संपादित करें जिसमें आपको "हुक" रखने की आवश्यकता है जिसे मूल डिजाइनर ने पूरा नहीं किया ; या, कोड "बंदर-पैच"। न तो अच्छा है, लेकिन दोनों काम कर सकते हैं, इसलिए कम से कम आभारी रहें कि हमारे पास ऐसे विकल्प हैं (ओपन-सोर्स और गतिशील भाषा का उपयोग करके)। इस मामले में, मुझे लगता है कि मैं बंदर पैचिंग के लिए जाना चाहते हैं (जो बुरा है, लेकिन कॉपी और पेस्ट कोडिंग और भी बदतर है) - इस तरह के रूप में एक कोड टुकड़ा:
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
अपने सटीक आवश्यकताओं के आधार पर (कर आपको सभी स्रोतों को एक ही स्रोत आईपी से बंधने की आवश्यकता है, या ...?) आप सामान्य रूप से urllib2
का उपयोग करने से पहले इसे चला सकते हैं, या (कोर्स के अधिक जटिल तरीकों से) इसे केवल उन आउटगोइंग सॉकेट के लिए जरूरी है जिन्हें आपको चाहिए एक निश्चित तरीके से बांधने के लिए (फिर प्रत्येक बार socket.socket = true_socket
को पुनर्स्थापित करने के लिए भविष्य में सॉकेट बनाने के तरीके से बाहर निकलने के लिए)। दूसरा विकल्प ठीक से ऑर्केस्ट्रेट करने के लिए अपनी जटिलताओं को जोड़ता है, इसलिए मैं आपको यह बताने के लिए इंतजार कर रहा हूं कि आपको उन सभी को समझाने से पहले ऐसी जटिलताओं की आवश्यकता है या नहीं। फिर भी नोट है कि यह वास्तव में अपने connect
विधि में socket.create_connection
पुन: पेश नहीं करता है, देखते हैं -
AKX के अच्छे जवाब "कॉपी/पेस्ट/संपादित करें" विकल्प पर एक प्रकार तो मैं विस्तार करने के लिए ज्यादा उस पर की आवश्यकता नहीं है स्रोत here (पृष्ठ के बहुत अंत में) और create_connection
फ़ंक्शन की अन्य कार्यक्षमता का निर्णय लें, यदि आप उस मार्ग पर जाने का निर्णय लेते हैं तो आप अपने कॉपी/पेस्ट/संपादित संस्करण में शामिल होना चाहेंगे।
न केवल एक पूर्ण उत्तर है, लेकिन, शायद, बंदर पैचिंग के अच्छे उपयोग का पहला उदाहरण मैंने कभी देखा है –
टीएक्स @ रॉबर्टो - यह "कम से कम बुराइयों" से अधिक है, लेकिन, हाँ, जब एक अमूर्तता का सामना करना पड़ता है यह आपकी जरूरतों के मुकाबले सील कर दिया गया है (आवश्यक हुक/"लीक" गायब हो रहा है), बंदरगाह "अच्छा" हो सकता है (उसी अर्थ में कि मरम्मत से परे बीमार है जो दांत खींच रहा है "अच्छा" ;-)। –
@ एलेक्स मार्टेलि: धन्यवाद। बंदर पैच बस ठीक काम किया! :) – jonasl
ऐसा लगता है कि यह काम करता है।
import urllib2, httplib, socket
class BindableHTTPConnection(httplib.HTTPConnection):
def connect(self):
"""Connect to the host and port specified in __init__."""
self.sock = socket.socket()
self.sock.bind((self.source_ip, 0))
if isinstance(self.timeout, float):
self.sock.settimeout(self.timeout)
self.sock.connect((self.host,self.port))
def BindableHTTPConnectionFactory(source_ip):
def _get(host, port=None, strict=None, timeout=0):
bhc=BindableHTTPConnection(host, port=port, strict=strict, timeout=timeout)
bhc.source_ip=source_ip
return bhc
return _get
class BindableHTTPHandler(urllib2.HTTPHandler):
def http_open(self, req):
return self.do_open(BindableHTTPConnectionFactory('127.0.0.1'), req)
opener = urllib2.build_opener(BindableHTTPHandler)
opener.open("http://google.com/").read() # Will fail, 127.0.0.1 can't reach google.com.
हालांकि, आपको "127.0.0.1" को पैरामीटर करने के लिए कुछ तरीका पता लगाना होगा। प्रमुख मुद्दा के इस ऑपरेशन में, HTTPConnection.connect
(httplib में) socket.create_connection
के प्रतिनिधियों, बारी में देता है जो -
यह पूरी तरह से काम करता है! बहुत धन्यवाद। –
@ डेवराक्स: आपको किस प्रणाली में सफलता मिली? मैं विंडोज 7 –
में नेटवर्क इंटरफेस को बांधने में असमर्थ हूं, लिनक्स और ओएसएक्स पर कोड मेरे लिए काम करता है। मैंने विंडोज़ पर सॉकेट कोड कभी नहीं लिखा है, लेकिन मुझे संदेह है कि उपयोगकर्ता की जगह में कच्चे सॉकेट की खिड़कियों की कमी से समस्याएं पैदा हो सकती हैं। –
मैंने सोचा कि मैं बंदर पैच के थोड़ा बेहतर संस्करण के साथ अनुवर्ती हूं। यदि आपको कुछ सॉकेट पर अलग-अलग बंदरगाह विकल्पों को सेट करने में सक्षम होना चाहिए या सॉकेट की तरह कुछ ऐसा उपयोग कर रहे हैं जो सॉकेट को उप-वर्गीकृत करता है, तो निम्न कोड थोड़ा बेहतर काम करता है।
_ip_address = None
def bind_outgoing_sockets_to_ip(ip_address):
"""This binds all python sockets to the passed in ip address"""
global _ip_address
_ip_address = ip_address
import socket
from socket import socket as s
class bound_socket(s):
def connect(self, *args, **kwargs):
if self.family == socket.AF_INET:
if self.getsockname()[0] == "0.0.0.0" and _ip_address:
self.bind((_ip_address, 0))
s.connect(self, *args, **kwargs)
socket.socket = bound_socket
यदि आप एक ही प्रक्रिया एक अलग आईपी पते के लिए बाध्य करने की जरूरत है कि में एक वेबसर्वर की तरह कुछ चलाने की आवश्यकता केवल कनेक्ट होने पर सॉकेट बाध्य करने के लिए है।
तर्क है कि मैं उच्चतम स्तर पर बंदर-पैच उपलब्ध होना चाहिए, यहाँ जो socket
के बजाय httplib
पैच, httplib.HTTPSConnection.__init__()
के source_address
कीवर्ड तर्क (जो urllib2
, AFAICT द्वारा उजागर नहीं किया गया है) का लाभ लेने एलेक्स के जवाब के लिए एक विकल्प है। परीक्षण और पायथन 2.7.2 पर काम कर रहा है।
import httplib
HTTPSConnection_real = httplib.HTTPSConnection
class HTTPSConnection_monkey(HTTPSConnection_real):
def __init__(*a, **kw):
HTTPSConnection_real.__init__(*a, source_address=(SOURCE_IP, 0), **kw)
httplib.HTTPSConnection = HTTPSConnection_monkey
यहाँ कि (अजगर 2.7 से प्रारंभ) HTTPConnection's source_address argument का उपयोग करता है एक और शोधन है:
import functools
import httplib
import urllib2
class BoundHTTPHandler(urllib2.HTTPHandler):
def __init__(self, source_address=None, debuglevel=0):
urllib2.HTTPHandler.__init__(self, debuglevel)
self.http_class = functools.partial(httplib.HTTPConnection,
source_address=source_address)
def http_open(self, req):
return self.do_open(self.http_class, req)
यह हमें एक कस्टम urllib2.HTTPHandler कार्यान्वयन source_address बारे में पता है कि देता है। हम इसे एक नया urllib2.OpenerDirector को जोड़ सकते हैं और डिफ़ॉल्ट सलामी बल्लेबाज (भविष्य urlopen() कॉल के लिए) के रूप में इसे स्थापित निम्न कोड के साथ:
handler = BoundHTTPHandler(source_address=("192.168.1.10", 0))
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
+1। मुझे लगता है कि पाइथन 2.7 के अद्यतन 'httplib' मॉड्यूल के साथ अनुशंसित विधि होनी चाहिए। वैसे, आईपीवी 4 एड्रेस स्ट्रिंग को कोट्स में रखा जाना चाहिए। मैंने आपकी पोस्ट को संपादित करने का प्रयास किया लेकिन इस तरह का छोटा बदलाव स्टैक ओवरफ्लो के तुच्छता फ़िल्टर को पास नहीं कर सका। –
अजगर के रूप में 2.7 httplib.HTTPConnection source_address इससे जुड़ा था, तो आप को देने की अनुमति एक आईपी पोर्ट जोड़ी से बांधने के लिए।
देखें: http://docs.python.org/2/library/httplib.html#httplib.HTTPConnection
- 1. पाइथन urllib2
- 2. पाइथन urllib2 जीवित रखने के साथ
- 3. कुकीज़ के साथ urllib2
- 4. पायथन और urllib2 के साथ विंडोज प्रमाणीकरण
- 5. urllib2
- 6. urllib2
- 7. urllib2 और json
- 8. पायथन और urllib2
- 9. पायथन - urllib2 और cookielib
- 10. पायथन: Urllib2 और OpenCV
- 11. urllib2
- 12. urllib2
- 13. एक इंटरफेस के साथ बातचीत?
- 14. IDISposable के साथ इंटरफेस विरासत?
- 15. पायथन urllib2: यूआरएल
- 16. टेस्सेरैक्ट इंटरफेस के साथ ओसीआर
- 17. HTTPS urllib2
- 18. कोको इंटरफेस के बेवकूफ, उत्तम दर्जे का, खुले स्रोत उदाहरण?
- 19. urllib2.urlopen
- 20. पायथन urllib2 प्रतिक्रिया शीर्षलेख
- 21. urllib2.URLError
- 22. पीछे के साथ पाइथन रेगेक्स और विकल्प
- 23. पायथन urllib2 HTTPS और प्रॉक्सी एनटीएलएम प्रमाणीकरण
- 24. छवि के साथ पाइथन खोज Google छवियों
- 25. स्रोत और अद्यतन स्रोत
- 26. पायथन: urllib/urllib2/httplib भ्रम
- 27. urllib2 स्ट्रिंग
- 28. पाइथन
- 29. एमईएफ और अलग इंटरफेस असेंबली "हर वर्ग के लिए इंटरफेस"
- 30. पाइथन
यह "अनुरोध" पुस्तकालय या pycurl उपयोग करने के लिए उचित है। यदि आप इसे गैर-तुच्छ कार्यों के लिए उपयोग करते हैं, तो आप हमेशा urllib2 के खराब डिज़ाइन पर ठोकर खा जाते हैं। – HighCat