Python
Børre Stenseth

Python og URL

Hva

Vi vil ofte av ulike grunner hente data fra en web adresse, en URL. Vi skal i denne modulen se på et par måter å gjøre dette på.

Kopier programkoden nedenfor og test den fra din egen maskin med alternative adresser og parametere.

Web-snifferen er et godt verktøy for a analysere hva som går over en HTTP konversasjon: [1]

urllib

Den enkleste måten å gjøre dette på er å bruke urllib. Vi kan ganske enkelt skrive:

import sys
from urllib import request
theUrl='https://borres.hiof.no/wep/python/mltxt/frej1.txt'
#Download a file and print it
try:
    f=request.urlopen(theUrl)
    S=f.read().decode() #since read returns bytes
    f.close()
    print (S)
except:
    res=sys.exc_info()
    print (res[1])

Du kan kopiere koden og kjøre programmet fra din harddisk.

Det er 3 mulige utfall av dette:

  1. Alt går vel og programmet returnerer den ønskede tekstfila
  2. Adressen har feil format, dvs. Python oppdager at dette kan umulig være en URL. I så fall får vi en exception og får utskriften:'cannot load'
  3. Adressen har riktig format, men den oppgitte adressen finnes ikke. I så fall får vi tilbake en utskrift: HTTP Error 404: Not Found

Merk at urllib også på en enkel måte lar oss kopiere en fil fra en URL til en lokal fil:

import sys
from urllib import request
theUrl='https://borres.hiof.no/wep/python/mltxt/frej1.txt'
theFile='frej1Copy.txt'
#Download a file and save it locally
try:
    request.urlretrieve( theUrl,theFile) 
except:
    res=sys.exc_info()
    print (res[1])

httplib

Med httlib kan vi skaffe oss mer kontroll. Her setter vi opp en forbindelse, connection, og vi kan kontrollere hva slags headerinformasjon vi får tilbake når vi forsøker å få kontakt. Blandt annet får vi opp feilen 404 når vi leter etter noe som ikke finnes. Vi forventer meldingen 200 når alt går bra.

"""
 read and print the content of an url
"""
import sys
from http import client
try:
    # set up a connection to host
    conn = client.HTTPConnection("borres.hiof.no")
    # send a get request for a certain file
    conn.request("GET", "/wep/python/mltxt/frej1.txt")
    # read the response, header
    r1 = conn.getresponse()
    # expect 200 as a signal for all is well
    if r1.status!=200:
        print ('access problem ',r1.status, r1.reason)    
    else:
        s=r1.read().decode()
        print (s)
    conn.close()
except:
    res=sys.exc_info()
    print (res[1])

Vi fanger opp situasjonen med ikke eksisterende server med en try - except. Nå ser vi at vi kan lese diagnosen på et leseforsøk uten å lese hele fila. Hodet, headeren, i forsøket på tilgang gir oss diagnosen. Kopier koden og forsøk å kjøre med å skrive inn en ikke-eksisterende server og alternativt med en ikke-eksistrende fil.

Vi kan også gjøre slik dersom vi skal sende med parametere til et cgi-skript og bruke POST:

"""
Access and use a remote script, with parameters
"""
import sys
from http import client
from urllib import parse
try:
    # prepare parameters
    params = parse.urlencode({'navn': 'ole', 'adresse': 'mysen'})
    # prepare header
    headers = {"Content-type": "application/x-www-form-urlencoded",
               "Accept": "text/plain"}
    # connect
    conn = client.HTTPConnection("borres.hiof.no")
    conn.request("POST", "/wp/commons/py/std.py", params, headers)
    r1 = conn.getresponse()
    # ok ?
    if r1.status!=200:
        print ('access problem ',r1.status, r1.reason)
    else:
        # get data
        s = r1.read().decode()
        print (s)
    conn.close()
except:
    res=sys.exc_info()
    print (res[1])
Referanser
  1. URL Content Dump Toolsvoid www.toolsvoid.com/url-dump 14-11-2014