Kirjoittaja Aihe: Valmiin Ircbotin Linkkien Encode Ongelma (Python) (Ratkaistu)  (Luettu 2719 kertaa)

Karvameduusa

  • Käyttäjä
  • Viestejä: 1055
    • Profiili
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:

Lainaus
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

Koodia: [Valitse]
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

Olen hyvin kiitollinen, jos tämän encode ongelma on helposti korjattavissa.
« Viimeksi muokattu: 27.03.12 - klo:23.59 kirjoittanut Karvameduusa »

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11433
    • Profiili
    • Tomin kotisivut
Vs: Valmiin Ircbotin Linkkien Encode Ongelma (Python)
« Vastaus #1 : 27.03.12 - klo:20.44 »
Auttaako lisätä alkuun:
Koodia: [Valitse]
# -*- coding: utf-8 -*-
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

SuperOscar

  • Käyttäjä
  • Viestejä: 3993
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Valmiin Ircbotin Linkkien Encode Ongelma (Python)
« Vastaus #2 : 27.03.12 - klo:21.02 »
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.
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 13.2-RELEASE; RPi 2: LibreELEC 11

Karvameduusa

  • Käyttäjä
  • Viestejä: 1055
    • Profiili
Vs: Valmiin Ircbotin Linkkien Encode Ongelma (Python)
« Vastaus #3 : 27.03.12 - klo:21.06 »
Auttaako lisätä alkuun:
Koodia: [Valitse]
# -*- coding: utf-8 -*-

Ei toiminut. Veikkaan että koodi täytyy muuta jostain tästä kohdasta:

Koodia: [Valitse]
    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)

SuperOscar

  • Käyttäjä
  • Viestejä: 3993
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Valmiin Ircbotin Linkkien Encode Ongelma (Python)
« Vastaus #4 : 27.03.12 - klo:21.52 »
Auttaako lisätä alkuun:
Koodia: [Valitse]
# -*- 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.
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 13.2-RELEASE; RPi 2: LibreELEC 11

Karvameduusa

  • Käyttäjä
  • Viestejä: 1055
    • Profiili
Vs: Valmiin Ircbotin Linkkien Encode Ongelma (Python)
« Vastaus #5 : 27.03.12 - klo:23.47 »
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.

Karvameduusa

  • Käyttäjä
  • Viestejä: 1055
    • Profiili
Vs: Valmiin Ircbotin Linkkien Encode Ongelma (Python)
« Vastaus #6 : 27.03.12 - klo:23.59 »
Ratkaisu:
title = re.sub("\s+", ' ', soup.title.string.encode('utf-8')).strip()

Hävettää vähän...


Karvameduusa

  • Käyttäjä
  • Viestejä: 1055
    • Profiili
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.

Koodia: [Valitse]
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])
« Viimeksi muokattu: 12.11.12 - klo:19.25 kirjoittanut Karvameduusa »