لا وكيل الثعبان الملتوي إطار الوصول HttpClient وإصلاحه؟

StackOverflow https://stackoverflow.com/questions/1651527

سؤال

وأنا بحاجة إلى الوصول إلى صفحة ويب باستخدام

twisted.web.client.getPage()

وأو طريقة مماثلة لتحميل صفحات الويب من عنوان معروف (أي: www.google.com)، والمشكلة هي: أنا وراء ملقم وكيل، وأنا لا يمكن أن تجد في أي مكان توضيحات حول كيفية تكوين الملتوية أو المصانع لاستخدام وكيل بلدي، أي أفكار؟

ونضع في اعتبارنا لدي لتحديد المستخدم وكلمة المرور المضيف والميناء. على بلدي لينكس آلة I http_proxy الإعداد وhttps_proxy إلى http://user:pwd@ip:port

والشكر مقدما.

هل كانت مفيدة؟

المحلول

from twisted.internet import reactor
from twisted.web import client

def processResult(page):
    print "I got some data", repr(page)
    reactor.callLater(0.1, reactor.stop)
def dealWithError(err):
    print err.getErrorMessage()
    reactor.callLater(0.1, reactor.stop)

class ProxyClientFactory(client.HTTPClientFactory):
    def setURL(self, url):
        client.HTTPClientFactory.setURL(self, url)
        self.path = url

factory = ProxyClientFactory('http://url_you_want')
factory.deferred.addCallbacks(processResult, dealWithError)

reactor.connectTCP('proxy_address', 3142, factory)
reactor.run()

نصائح أخرى

لتحصل على حل nosklo للعمل سوف تحتاج إلى إنشاء معالج آخر لل"401" الذي يشير إلى أن هناك حاجة المصادقة. جرب شيئا مثل هذا

def checkAuthError(self,failure,url):
    failure.trap(error.Error)
    if failure.value.status == '401':
        username = raw_input("User name: ")
        password = getpass.getpass("Password: ")
        auth = base64.encodestring("%s:%s" %(username, password))
        header = "Basic " + auth.strip()
        return client.getPage(
            url, headers={"Authorization": header})
    else:
        return failure

وهذا سيدفع المشغل لتوفير المعلومات في سطر الأوامر، أو كنت زوجين يمكن أن توفر اسم المستخدم وكلمة المرور في وسيلة أخرى من اختيارك. تأكد هذا هو معالج الأول واضاف باعتبارها Errback، قبل يتم إضافة أي معالجات أخرى حتى الاستدعاء. وهذا يتطلب أيضا عدد قليل من زيادة الواردات. "base64 في '،' getpass '، و' خطأ 'للعمل مع يطالب سطر الأوامر.

وكان علي أن أفعل شيئا من هذا القبيل باستخدام المصادقة الأساسية، منذ رمز المثال لطلب المصادقة لم ينجح هنا هو الإصدار الذي يعمل:

import base64

from twisted.internet import defer, reactor
from twisted.web import client, error, http

from ubuntuone.devtools.testcases.squid import SquidTestCase

# ignore common twisted lint errors
# pylint: disable=C0103, W0212


class ProxyClientFactory(client.HTTPClientFactory):
    """Factory that supports proxy."""

    def __init__(self, proxy_url, proxy_port, url, headers=None):
        self.proxy_url = proxy_url
        self.proxy_port = proxy_port
        client.HTTPClientFactory.__init__(self, url, headers=headers)

    def setURL(self, url):
        self.host = self.proxy_url
        self.port = self.proxy_port
        self.url = url
        self.path = url


class ProxyWebClient(object):
    """Provide useful web methods with proxy."""

    def __init__(self, proxy_url=None, proxy_port=None, username=None,
            password=None):
        """Create a new instance with the proxy settings."""
        self.proxy_url = proxy_url
        self.proxy_port = proxy_port
        self.username = username
        self.password = password

    def _process_auth_error(self, failure, url, contextFactory):
        """Process an auth failure."""
        # we try to get the page using the basic auth
        failure.trap(error.Error)
        if failure.value.status == str(http.PROXY_AUTH_REQUIRED):
            auth = base64.b64encode('%s:%s' % (self.username, self.password))
            auth_header = 'Basic ' + auth.strip()
            factory = ProxyClientFactory(self.proxy_url, self.proxy_port, url,
                    headers={'Proxy-Authorization': auth_header})
            # pylint: disable=E1101
            reactor.connectTCP(self.proxy_url, self.proxy_port, factory)
            # pylint: enable=E1101
            return factory.deferred
        else:
            return failure

    def get_page(self, url, contextFactory=None, *args, **kwargs):
        """Download a webpage as a string.

        This method relies on the twisted.web.client.getPage but adds and extra
        step. If there is an auth error the method will perform a second try
        so that the username and password are used.
        """
        scheme, _, _, _ = client._parse(url)
        factory = ProxyClientFactory(self.proxy_url, self.proxy_port, url)
        if scheme == 'https':
            from twisted.internet import ssl
            if contextFactory is None:
                contextFactory = ssl.ClientContextFactory()
            # pylint: disable=E1101
            reactor.connectSSL(self.proxy_url, self.proxy_port,
                               factory, contextFactory)
            # pylint: enable=E1101
        else:
            # pylint: disable=E1101
            reactor.connectTCP(self.proxy_url, self.proxy_port, factory)
            # pylint: enable=E1101
        factory.deferred.addErrback(self._process_auth_error, url,
                                    contextFactory)
        return factory.deferred

ولقد اخترنا لاستخدام متغير البيئة http_proxy. كنا تواجه مشكلة مع إعادة توجيه يست دائما الحصول على التقطت، أو بالأحرى الحصول على التقطت في الطريق الصحيح. وقال، ردا nosklo في حقا ساعد!

import os
from twisted.web import client

class ProxyClientFactory(client.HTTPClientFactory):
    def setURL(self, url):
        '''More sensitive to redirects that can happen, that
        may or may not be proxied / have different proxy settings.'''
        scheme, host, port, path = client._parse(url)
        proxy = os.environ.get('%s_proxy' % scheme)
        if proxy:
            scheme, host, port, path = client._parse(proxy)
            self.scheme = scheme
            self.host = host
            self.port = port
            self.path = url
            self.url = url
        else:
            client.HTTPClientFactory.setURL(self, url)

factory = ProxyClientFactory(url)
# Callback configuration
# If http_proxy or https_proxy, or whatever appropriate proxy
# is set, then we should try to honor that. We do so simply 
# by overriding the host/port we'll connect to. The client
# factory, BaseRequestServicer takes care of the rest
scheme, host, port, path = client._parse(url)
proxy = os.environ.get('%s_proxy' % scheme)
if proxy:
    scheme, host, port, path = client._parse(proxy)
reactor.connectTCP(host, port, factory)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top