#include #include #include #include #include #include #include #include #include #include #include #include "srunnable.h" #include "data.h" extern void Debug(QString _strFilename,QString _strData); SRunnable::SRunnable(int _nSelect) { m_pstrOut = 0; m_nSelect = _nSelect; } SRunnable::~SRunnable() { } void SRunnable::RunNaverNews() { QHostInfo info = QHostInfo::fromName("comment.news.naver.com"); QTcpSocket socket; socket.connectToHost(info.addresses().at(rand()%info.addresses().size()).toString(),80); if(!socket.waitForConnected()) { qDebug() << "Error: " << socket.errorString(); } socket.write(QString("POST /api/reply/list.json HTTP/1.1\r\n" "Host: comment.news.naver.com\r\n" "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" "Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3\r\n" "Accept-Encoding: deflate\r\n" "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" "charset: utf-8\r\n" "Content-Length: " + QString::number(m_strParam.length()) + "\r\n" "Connection: keep-alive\r\n" "Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n\r\n" + m_strParam).toUtf8()); QByteArray byArray; while (socket.waitForReadyRead()) { byArray += socket.readAll(); } QJsonDocument d; { QJsonParseError error; int index = byArray.indexOf("{"); byArray=byArray.mid(index-2); bool bFlag = true; QString strOut; while(bFlag) { strOut += byArray.left(8188); byArray=byArray.mid(8192); if (byArray.size() <= 8192) { bFlag = false; strOut += byArray; } } strOut = strOut.replace("\r\n","").replace("\n",""); { QRegExp re("\\}\\}[\\w\\s]*$"); strOut = strOut.replace(re,"}}"); } if (strOut.length() <= 0 ) return; d = QJsonDocument::fromJson(strOut.trimmed().toUtf8(),&error); if (error.error != 0) { qDebug() << error.errorString(); Debug("reply.json",strOut); socket.close(); exit(0); } } QString astrOut[E_REPLY_MAX]; foreach(QJsonValue value ,d.object().value("message").toObject().value("result").toObject().value("commentReplies").toArray()) { QJsonObject obj = value.toObject(); int i= E_REPLY_USER_ID; while (i < E_REPLY_MAX) { if (i <= E_REPLY_CONTENT) astrOut[i] = obj[g_strJsonReplyHead[i]].toString(); else astrOut[i] = QString::number(obj[g_strJsonReplyHead[i]].toInt()); i++; } for (i = 0; i < E_REPLY_MAX;i++) { QString strOut = g_strJsonReplyHead[i] + " : " + astrOut[i]; m_pstrOut->push_back(strOut); } m_pstrOut->push_back(""); } socket.close(); } QString CharToUnicode(QString _str) { QString str = _str.replace("\\u",""); QByteArray _byArray = str.toUtf8(); unsigned short ushCode = 0; for (int i=0; i < 4 ; i++) { if(_byArray.at(i) >= '0' && _byArray.at(i) <= '9' ) ushCode |= (_byArray.at(i) - '0') << ((3-i)*4); if(_byArray.at(i) >= 'A' && _byArray.at(i) <= 'F' ) ushCode |= (_byArray.at(i) - 'A' + 10) << ((3-i)*4); } return QString(QChar(ushCode)); } QString StringToUniCode(QString _str) { QRegExp rx("(\\\\u[0-9a-fA-F]{4})"); int pos = 0; while((pos = rx.indexIn(_str, pos))!= -1) _str.replace(pos, rx.matchedLength(), CharToUnicode(rx.cap(1))); return _str; } void SRunnable::RunDaumCafe() { QHostInfo info = QHostInfo::fromName("cafe.daum.net"); QTcpSocket socket; socket.connectToHost(info.addresses().at(rand()%info.addresses().size()).toString(),80); if(!socket.waitForConnected()) { qDebug() << "Error: " << socket.errorString(); } socket.write(m_strParam.toUtf8()); QByteArray byArray; while (socket.waitForReadyRead()) byArray += socket.readAll(); QString strOut; foreach (QByteArray byData ,byArray.split('\n')) { byData = byData.replace('\r',""); if (byData.size() == 5 || byData.size() == 4 ) { int i = 0; foreach(QChar ch,byData.left(4)) { if (ch.isDigit()) i++; if (ch >= 'a' && ch <= 'f') i++; } if (i == 4) continue; } strOut += byData; } strOut=strOut.replace("\\t","\t").replace("\\r\\n","\r\n").replace("\\\"","\"").replace("\\'","'"); int nMode = -1; bool bDate = false; bool bContent = false; int nCount = -1; bool bReply = false; QString strParent; QString strPreviousID; struct SData { QString m_strContent; QString m_strNick; QString m_strDate; QString m_strParent; QString m_strID; }; SData astData[50]; //read line by line from ajax script foreach(QString str,strOut.split("\n")) { str = str.trimmed(); if (str.isEmpty()) continue; if (str.indexOf(QString("class=\"comment_pos\"")) > -1 ) {bReply = false;nMode = 0;nCount++;} else if (str.indexOf(QString("class=\"recomment_pos recomment_first\"")) > -1 ) {bReply = true;nMode = 0;nCount++;} else if (str.indexOf(QString("class=\"recomment_pos\"")) > -1) {bReply = true;nMode = 0;nCount++;} if (bDate && nCount >= 0) astData[nCount].m_strDate = str; if (bContent && nCount >= 0) astData[nCount].m_strContent = str; bDate = (str.indexOf(QString("class=\"comment_date txt_sub p11 ls0\"")) > -1); // date is in next line bContent = (str.indexOf(QString("class=\"comment_contents\"")) > -1); // content is in next line // check id, nickname if (str.indexOf(QString("onclick=\"showSideView(this")) > -1) { { int nFirst = str.indexOf("'")+1; int nLast = str.indexOf("'",nFirst); if (nFirst > -1 && nLast > -1) { strPreviousID = astData[nCount].m_strID; astData[nCount].m_strID = str.mid(nFirst,nLast-nFirst); } } { int nFirst = str.indexOf(QString("class=\"b\">")) + QString("class=\"b\">").length(); int nLast = str.indexOf(QString("")); if (nFirst > -1 && nLast > -1) astData[nCount].m_strNick = str.mid(nFirst,nLast-nFirst); if (bReply == false) strParent = astData[nCount].m_strNick; else astData[nCount].m_strParent = strParent; // if sub reply, then put parent } } // check sub sub reply if (str.indexOf(QString("class=\"mention_nicknames text_counter txt_point b\">")) > -1 ) { int nFirst = str.indexOf(QString("class=\"mention_nicknames text_counter txt_point b\">")) + QString("class=\"mention_nicknames text_counter txt_point b\">").length(); int nLast = str.indexOf(QString("")); nMode = 1; astData[nCount].m_strParent = str.mid(nFirst,nLast-nFirst); astData[nCount].m_strID = strPreviousID; } // nMode : 0-normal reply or reply reply. 1,2-reply reply reply. 2-contents switch(nMode) { case 1: if (str == "") nMode = 2; break; case 2: astData[nCount].m_strContent = str; nMode = 0; break; } } for(int i = 0; i < 50; i++) { if (astData[i].m_strDate.isEmpty()) continue; if (astData[i].m_strNick.isEmpty()) continue; m_pstrOut->push_back(astData[i].m_strDate.trimmed().replace(".","-").replace("- "," ")); m_pstrOut->push_back(StringToUniCode(astData[i].m_strContent)); m_pstrOut->push_back(StringToUniCode(astData[i].m_strNick)); m_pstrOut->push_back(StringToUniCode(astData[i].m_strParent)); m_pstrOut->push_back(StringToUniCode(astData[i].m_strID)); m_pstrOut->push_back(QString::number(m_strID.toInt()*50 + i)); } socket.close(); } void SRunnable::run() { switch(m_nSelect) { case E_NAVER_NEWS:RunNaverNews();break; case E_DAUM_CAFE:RunDaumCafe();break; } }