Ubuntu Suomen keskustelualueet
Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: Karvameduusa - 27.03.12 - klo:20.10
-
Terve en ole koodaaja, mutta kysyn otsikon mukaista asiaa. Asia liittyy pythonilla koodattuun linkkien näyttäjä bottiin. Botti ei hallitse UTF-8 merkistöä.
Virheilmoitus pastetun urlin jälkeen:
File "rollbot.py", line 34, in privmsg
self.msg(self.factory.channel, "Title: %s" % str(title))
exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 21: ordinal not in range(128)
Botin lähdekoodit
import sys
import re
import urllib
import BeautifulSoup
from HTMLParser import HTMLParseError
from twisted.words.protocols import irc
from twisted.internet import protocol, reactor
class MyBot(irc.IRCClient):
def _get_nickname(self):
return self.factory.nickname
nickname = property(_get_nickname)
def signedOn(self):
self.join(self.factory.channel)
print "Signed on as %s." % (self.nickname)
def joined(self, channel):
print "Joined %s." % channel
def privmsg(self, user, channel, msg):
# get title of urls
matches = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', msg)
if matches:
for url in matches:
u = urllib.urlopen(url)
urltype = u.headers.gettype()
print urltype
try:
soup = BeautifulSoup.BeautifulSoup(u)
title = re.sub("\s+", ' ', soup.title.string).strip()
self.msg(self.factory.channel, "Title: %s" % str(title))
except (AttributeError, HTMLParseError):
u = urllib.urlopen(url)
self.msg(self.factory.channel, \
"NO TITLE FOUND (%s)" % urltype)
class MyBotFactory(protocol.ClientFactory):
protocol = MyBot
def __init__(self, channel, nickname="Rollbot"):
self.channel = channel
self.nickname = nickname
def clientConnectionLost(self, connector, reason):
print "Lost connection (%s), reconnecting." % reason
connector.connect()
def clientConnectionFailed(self, connector, reason):
print "Could not connect: %s" % reason
if __name__ == "__main__":
try:
chan = sys.argv[1]
reactor.connectTCP('irc.freenode.net', 6667, MyBotFactory('#' + chan))
reactor.run()
except IndexError:
print "Please specify a channel name."
print "Example:"
print " python %s somechannel" % sys.argv[0]
Virallinen linkki bottiin:
https://github.com/redseam/Rollbot/blob/master/rollbot.py (https://github.com/redseam/Rollbot/blob/master/rollbot.py)
Olen hyvin kiitollinen, jos tämän encode ongelma on helposti korjattavissa.
-
Auttaako lisätä alkuun:
# -*- coding: utf-8 -*-
-
Jollei Tominin ehdotus riitä avuksi, helpoimmalla pääset jos pystyt vaihtamaan Pythonin kolmosversioon. Tarvittavat muutokset skriptiin ovat pieniä (esim. print "jotakin" muuttuu muotoon print("jotakin")), mutta kaikki tuollainen ärsyttävä merkistökoodaussekoilu loppuu.
Itse tappelin pitkään yhden pienen lokausskriptin kanssa, mutta muuta ratkaisua en löytänyt.
-
Auttaako lisätä alkuun:
# -*- coding: utf-8 -*-
Ei toiminut. Veikkaan että koodi täytyy muuta jostain tästä kohdasta:
def privmsg(self, user, channel, msg):
# get title of urls
matches = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', msg)
if matches:
for url in matches:
u = urllib.urlopen(url)
urltype = u.headers.gettype()
print urltype
try:
soup = BeautifulSoup.BeautifulSoup(u)
title = re.sub("\s+", ' ', soup.title.string).strip()
self.msg(self.factory.channel, "Title: %s" % str(title))
except (AttributeError, HTMLParseError):
u = urllib.urlopen(url)
self.msg(self.factory.channel, \
"NO TITLE FOUND (%s)" % urltype)
-
Auttaako lisätä alkuun:
# -*- coding: utf-8 -*-
Ei toiminut. Veikkaan että koodi täytyy muuta jostain tästä kohdasta:
Usko pois, olet lähes toivottoman tehtävän edessä. Voit yrittää pelehtiä str.encode()- ja str.decode()-funktioiden kanssa, mutta lopputulos on järjetön suo.
Paljon helpommalla pääset, kun teet pari pientä muutosta ja ajat skriptiäsi Python 3:lla.
-
Paljon helpommalla pääset, kun teet pari pientä muutosta ja ajat skriptiäsi Python 3:lla.
Koodaus taitoni ei ole hyvää. En tiedä miten lähteä korjaamaan kyseistä koodia.
-
Ratkaisu:
title = re.sub("\s+", ' ', soup.title.string.encode('utf-8')).strip()
Hävettää vähän...
-
Olen vähän parannellut tätä bottia. Toimii nykyisin python 3:lla ja osaa tulostaa joitakin erikoismerkkejä. Esimerkiksi ä ö lähinnä iltalehden sivuilta oleva koodauksen takia jouduin tekemään.
import sys
import re
import urllib
# import urllib2
import BeautifulSoup
from HTMLParser import HTMLParseError
from twisted.words.protocols import irc
from twisted.internet import protocol, reactor
class MyBot(irc.IRCClient):
def _get_nickname(self):
return self.factory.nickname
nickname = property(_get_nickname)
def signedOn(self):
self.join(self.factory.channel)
print ("Signed on as %s." % (self.nickname))
def joined(self, channel):
print ("Joined %s." % channel)
def privmsg(self, user, channel, msg):
# get title of urls
matches = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', msg)
if matches:
for url in matches:
u = urllib.urlopen(url)
urltype = u.headers.gettype()
print (urltype)
try:
soup = BeautifulSoup.BeautifulSoup(u)
title = re.sub("\s+", ' ', soup.title.string.encode('utf-8')).strip()
# pienet aakkoset
title = title.replace("ä", "\xe4")
title = title.replace("ö", "\xf6")
title = title.replace("å", "\xe5")
# isot aakkoset
title = title.replace("Ä", "\xc4")
title = title.replace("Ö", "\xd6")
title = title.replace("Å", "\xc5")
self.msg(self.factory.channel, "Title: %s" % str(title))
except (AttributeError, HTMLParseError):
u = urllib.urlopen(url)
self.msg(self.factory.channel, \
"NO TITLE FOUND (%s)" % urltype)
class MyBotFactory(protocol.ClientFactory):
protocol = MyBot
def __init__(self, channel, nickname="botinnimi"):
self.channel = channel
self.nickname = nickname
def clientConnectionLost(self, connector, reason):
print ("Lost connection (%s), reconnecting." % reason)
connector.connect()
def clientConnectionFailed(self, connector, reason):
print ("Could not connect: %s" % reason)
if __name__ == "__main__":
try:
chan = sys.argv[1]
reactor.connectTCP('irc.quakenet.org', 6667, MyBotFactory('#' + chan))
reactor.run()
except IndexError:
print ("Please specify a channel name.")
print ("Example:")
print (" python %s somechannel" % sys.argv[0])