لا وكيل الثعبان الملتوي إطار الوصول HttpClient وإصلاحه؟
-
22-07-2019 - |
سؤال
وأنا بحاجة إلى الوصول إلى صفحة ويب باستخدام
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)