Probleem met character sets in Qt

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer in Qt een webcrawler te maken. Ik gebruik nu voor dat doel een antiek powershell script, waar ik eigenlijk tegen dezelfde problemen aan liep: character sets. Dat heb ik destijds opgelost door een boel replace commands, maar dat is natuurlijk niet zo elegant.

Neem bijvoorbeeld de pagina http://configure.euro.del...dhs1&vw=classic&~lt=print. In mijn browser wordt hij correct gerenderd:
Afbeeldingslocatie: http://tweakers.net/ext/f/JGi7259tLer7rsUqQyOMb6AM/full.png

Download ik de pagina via mijn programmatje en output ik deze naar een file, dan zijn de resultaten niet zo mooi:
Afbeeldingslocatie: http://tweakers.net/ext/f/U6e0iWWBhNsXT3iZ1Gdcu4w4/full.png
datzelfde, in een hex editor:
code:
1
E2 3F AC C2 A0 37 37 38 2C 30 30

� 778,00 in latin-1 komt er dan uitrollen volgens die uitstekende converter van .oisyn. Maar ik krijg het niet voor elkaar een fatsoenlijke output te krijgen. Zelfs als ik meerdere stappen probeer (latin1 -> UTF-8 -> ...)

relevant code snippet:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Networker::download(const char* url)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    connect(manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(replyFinished(QNetworkReply*)));

    manager->get(QNetworkRequest(QUrl(url)));
}


void Networker::replyFinished(QNetworkReply* reply)
{    
    QString data(reply->readAll());    // readAll geeft een QByteArray terug

//    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
//    data = codec->toUnicode(data.toStdString().c_str());

    // sla data naar file..
}

Dat uitgecommente stuk code is natuurlijk waar de conversie van het juist characterset moet gebeuren. Maar ik ben al het hele weekend bezig om uit te zoeken wélk obscuur character set er wordt gebruikt. Daar moet toch een truukje voor zijn?

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Die pagina is UTF-8. Mogelijk mist je font een paar characters ofzo

De source is trouwens niet de HEX die jij daar claimed, maar
code:
1
e2 82 a0 20 37 37 38 2c 30 30

e2 82 a0 is het euro teken

Edit: nee, je hebt 3 output characters voor 3 bytes, ergens interpreteer je UTF8 als ASCII of een ANSI codepage oid.

[ Voor 73% gewijzigd door MLM op 13-05-2012 19:38 ]

-niks-


Acties:
  • 0 Henk 'm!

  • Lone Gunman
  • Registratie: Juni 1999
  • Niet online
Als je de documentatie van QString bekijkt zie je dat het fout gaat op regel 14 van je snippet:
QString::QString ( const QByteArray & ba )
Constructs a string initialized with the byte array ba. The given byte array is converted to Unicode using fromAscii(). Stops copying at the first 0 character, otherwise copies the entire byte array.
Je QByteArray is in dit geval UTF-8, dus dat gaat fout. Afhankelijk van wat je wilt zou je de data direct naar disk kunnen schrijven zonder tussenkomst van een QString, dan hoef je niet eens te kijken naar de encoding.

De encoding kun je trouwens achterhalen via de header van de reply, bv via reply->rawHeaderPairs();

Experience has taught me that interest begets expectation, and expectation begets disappointment, so the key to avoiding disappointment is to avoid interest.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Lone Gunman schreef op zondag 13 mei 2012 @ 21:02:
Als je de documentatie van QString bekijkt zie je dat het fout gaat op regel 14 van je snippet:


[...]


Je QByteArray is in dit geval UTF-8, dus dat gaat fout.
Dat zou best kunnen. Ik ga er eens mee knutselen.
Afhankelijk van wat je wilt zou je de data direct naar disk kunnen schrijven zonder tussenkomst van een QString, dan hoef je niet eens te kijken naar de encoding.
Dat kan niet, ik wil een een regex over de content halen, en die opslaan in XML. Vroeg of laat moet je dan converteren naar QString.
De encoding kun je trouwens achterhalen via de header van de reply, bv via reply->rawHeaderPairs();
Die kende ik nog niet. Dat is inderdaad UTF-8.

Edit: volgens mij heb ik hem...

C++:
1
2
3
4
5
6
    out << "<br>content direct       " << content << endl;
    out << "<br>content as constdata " << content.constData() << endl;
    out << "<br>content as QString   " << QString(content) << endl;
    out << "<br>content from ascii   " << QString::fromAscii(content) << endl;
    out << "<br>content from latin   " << QString::fromLatin1(content) << endl;
    out << "<br>content from utf8    " << QString::fromUtf8(content) << endl;

waar content de QByteArray is van een file geëncodeerd in UTF-8, met als inhoud een enkel euroteken. Geeft als output:
code:
1
2
3
4
5
6
content direct �
content as constdata �
content as QString �
content from ascii �
content from latin �
content from utf8 €

Die laatste moet ik dus hebben. Even inbouwen in mijn programma, en testen maar :)

edit: yep, hij werkt eindelijk. Ik zat nog een uur te klooien voordat ik me realiseerde dat ik het document als ANSI opsoeg, terwijl er een content-type utf-8 staat gedeclareerd in die webpagina. Dan toont je browser het natuurlijk verkeerd...

[ Voor 40% gewijzigd door Verwijderd op 13-05-2012 23:39 ]