Snippet: Proxy-Server bei urllib und mechanize hinterlegen

Snippet: Proxy-Server bei urllib und mechanize hinterlegen

Bash SSHWer mit Python hinter einem Proxy-Server arbeitet und mit Ressourcen aus dem Internet arbeitet der muss diesen in Python bekanntmachen. Leider gibt es in Python keine globale Variante einen Proxy für die komplette Netzwerkkommunikation zu hinterlegen.
Ich habe mich mit dem Thema beschäftigt, weil ich kürlich selbst vor dem Problem mit dem Proxy gestanden habe.

Wie man in Python urllib und mechanize verwendet habe ich erst kürzlich in einem anderen Artikel demonstriert.
Bei den genannten Paketen müssen Proxies immer mit dem Datentyp Dict hinterlegt werden. In etwas so:

proxy = {'http':'http://192.168.0.2:8080'}

Ich will diesen proxy nun aber nicht bei jedem Aufruf der oben genannten Pakete neu definieren. Was würde sich also anbieten?

  • Eine globale Konfigurationsvariable,
  • eine Config-Datei mit Config-Parser einlesen und entsprechend an die Funktionsaufrufe mitgeben

Die einfachste Möglichkeit ist eine globale Konfigurationsvariable zu definieren. Das ist zwar nicht wirklich sauber, aber es funktioniert.Dazu habe ich mal mein Beispielskript aus dem „urllib und mechanize Artikel“ leicht modifiziert:

import urllib
import mechanize
proxies = {"http" : "http://192.168.0.2:8080"}
 
def website_title(url):
  response = urllib.urlopen(url,None,proxies)
  for l in response:
    if l.find('') >= 0:
      return l.strip()[l.find('')+7:l.find('')]
 
def website_title2(url):
  br = mechanize.Browser()
  br.set_proxies(proxies)
  br.open(url)
  return br.title()
 
if __name__ == '__main__':
  print website_title('http://city-insider.de')
  print website_title2('http://city-insider.de')

Bei dieser Variante wird der in der Variable proxies hinterlegte Proxy definiert und von beiden Funktionen (website_title und website_title2) genutzt. Die andere vielleicht etwas elegantere Methode den Proxy zu definieren ist es ein Konfigurations-File zu verwenden. Das hat den entscheidenden Vorteil, dass ihr den Proxy für all eure Skripte genau einmal definieren müsst und diesen bei Bedarf auch nur einmal anpassen müsst. Zum lesen der Konfiguration bietet sich das Modul ConfigParser an. Dieses ist Teil der Python Standard-Library, somit muss nichts extra nachinstalliert werden.

def get_config(configfile="proxy.conf"):
  import ConfigParser
  config = ConfigParser.RawConfigParser()
  config.read(configfile)
  proxy = config.get('settings', 'proxy')
  return {'http':proxy}

Das Konfigurationsfile sieht in diesem Fall folgendermaßen aus:

[settings]
proxy = http://192.168.0.2:8080

So könnt ihr diese Funktion in das obige Skript integrieren:

import urllib
import mechanize
 
def get_config(configfile="proxy.conf"):
  import ConfigParser
  config = ConfigParser.RawConfigParser()
  config.read(configfile)
  proxy = config.get('settings', 'proxy')
  return {'http':proxy}
 
def website_title(url):
  response = urllib.urlopen(url,None,proxies)
  for l in response:
    if l.find('') >= 0:
      return l.strip()[l.find('')+7:l.find('')]
 
def website_title2(url):
  br = mechanize.Browser()
  br.set_proxies(proxies)
  br.open(url)
  return br.title()
 
if __name__ == '__main__':
  proxies = get_config()
  print website_title('http://city-insider.de')
  print website_title2('http://city-insider.de')

Übrigens: Wenn ihr eine Environment-Variable „http_proxy“ setzt, dann erkennt Python diese automatisch und nutzt diese auch. Das heißt, diese Variante ist den beiden obigen Varianten in jedem Fall vorzuziehen.