Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Поиск RSS новостных сайтов

Anna | 24.06.2014 | нет комментариев

Покопался я ещё в своих ветхих и не дюже планах и нашёл одну увлекательную программку. Она ищет RSS ссылки новостных сайтов. Задача которая стояла — это обнаружить как дозволено огромнее новостных RSS лент и собрать их всех в одну базу.

Когда встал вопрос о том как искать новостные сайты, пришла мысль о применении обслуживания news.google.com. От туда дозволено выдёргивать ссылки на новостные сайты, к тому же они непрерывно добавляются и отсортированы по регионам, темам и т.д. Осталось пройтись по каждому разделам news.google.com, выдернуть ссылки новостных сайтов, а после этого обнаружить все RSS всякого из них.

Вначале код. Он состоит из следующих файлов: main.cpp LinksReader.cpp LinksReader.h LinksReader.pro Sources.txt и файл тот, что создастся механически и в котором сохранится итог RssLinks.txt. Каждая логика содержится в файлах LinksReader.h и LinksReader.cpp, остальные файлы вспомогательные, для применения класса и компилирования плана. Компилировал план в с поддержкой компилятора g , среда Qt creator, версия библиотек 5.1

LinksReader.h

#ifndef LINKSREADER_H
#define LINKSREADER_H

#include <QStringList>
#include <QFile>
#include <QNetworkReply>
#include <QEventLoop>
#include <QDebug>

class LinksReader: public QObject
{
    Q_OBJECT

private:
    void loadSources();
    void loadRssLinks();
    void readPage(QString url);
    void takeLinks();
    void takeRssLinks();
    void saveRssLinks();

    QNetworkAccessManager mNAManager;
    QString               mPage;
    QString               mPageUrl;
    QStringList           mSources;
    QStringList           mLinks;
    QStringList           mRssLinks;

private slots:
    void onReplyFinished(QNetworkReply *pReply);

public:
    LinksReader(QObject *pParent = 0);
    void run();
};

#endif

LinksReader.cpp

#include "LinksReader.h"

void LinksReader::loadSources()
{
    QString fileName = "Sources.txt";

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "File " << fileName << " not found";
        return;
    }

    QTextStream in(&file);

    while(!in.atEnd())
        mSources.push_back(in.readLine());

    file.close();

    qDebug() << mSources.size() << " sources loaded";
    return;
}

void LinksReader::loadRssLinks()
{
    QString fileName = "RssLinks.txt";

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QTextStream in(&file);

    while(!in.atEnd())
        mRssLinks.push_back(in.readLine());

    file.close();

    qDebug() << mRssLinks.size() << " rss links loaded";
    return;
}

void LinksReader::readPage(QString url)
{
    mPage    = "";
    mPageUrl = url;

    mNAManager.get(QNetworkRequest(QUrl(url)));

    QEventLoop loop;
    QObject::connect(&mNAManager, SIGNAL(finished(QNetworkReply *)), &loop, SLOT(quit()));
    loop.exec();
}

void LinksReader::takeLinks()
{
    QStringList fullLinks;
    QString links  = "";

    QString beginTN    = "<link>";
    QString endTN      = "</link>";
    QString tagContent = "";

    int beginTP = 0;
    int endTP   = 0;

    while(1)
    {
        beginTP = mPage.indexOf(beginTN);
        endTP   = mPage.indexOf(endTN);
        if (beginTP == -1 || endTP == -1) break;

        tagContent = mPage.mid(beginTP   beginTN.length(), endTP - beginTP - endTN.length()   1);

        links  = tagContent;
        mPage.remove(0, endTP   endTN.length());
    }

    fullLinks = links.split("http://");
    fullLinks.removeFirst();

    for(int i = 0; i < fullLinks.size(); i  )
    {
        fullLinks[i].remove(fullLinks[i].indexOf("/"), fullLinks[i].length());
        mLinks.push_back(fullLinks[i]);
    }
}

void LinksReader::takeRssLinks()
{
    QString beginTN    = "<link";
    QString endTN      = ">";
    QString tagContent = "";

    QString beginRssString = "href=\"";
    QString endRssString   = " ";

    int beginTP = 0;
    int endTP   = 0;

    while(1)
    {
        beginTP = mPage.indexOf(beginTN);
        endTP   = mPage.indexOf(endTN, beginTP);
        if (beginTP == -1 || endTP == -1) break;

        beginTP  = beginTN.length();
        tagContent = mPage.mid(beginTP, endTP - beginTP);

        if (tagContent.indexOf("type=\"application/rss xml\"") != -1)
        {
            int beginRssPos = tagContent.indexOf(beginRssString);
            int endRssPos   = tagContent.indexOf(endRssString, beginRssPos);

            beginRssPos  = beginRssString.size();

            QString rssString = tagContent.mid(beginRssPos, endRssPos - beginRssPos).remove("\"");

            if (rssString.size() > 0 && rssString[rssString.size() - 1] == '/')
                rssString.remove(rssString.size() - 1, 1);

            if (rssString.indexOf("http://") == -1)
rssString.push_front(mPageUrl);

            qDebug() << rssString;
            mRssLinks.push_back(rssString);
        }

        mPage.remove(0, endTP   endTN.length());
    }
}

void LinksReader::saveRssLinks()
{
    QFile file("RssLinks.txt");
    file.open(QFile::ReadWrite);
    QTextStream in(&file);

    for(int i = 0; i < mRssLinks.size(); i  )
        in << mRssLinks[i] << "\n";

    file.close();
}

void LinksReader::onReplyFinished(QNetworkReply *reply) {
    mPage  = reply->readAll();
}

LinksReader::LinksReader(QObject *pParent): QObject(pParent) {
    QObject::connect(&mNAManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(onReplyFinished(QNetworkReply *)));
}

void LinksReader::run()
{
    loadSources ();
    loadRssLinks();

    qDebug() << "Please wait...";

    for(int i = 0; i < mSources.size(); i  )
    {
        readPage(mSources[i]);
        takeLinks();
    }

    mLinks.removeDuplicates();

    for(int i = 0; i < mLinks.size(); i  )
    {
        readPage("http://"   mLinks[i]);
        takeRssLinks();
    }

     mRssLinks.removeDuplicates();

    saveRssLinks();

    qDebug() << "Finish";
}

main.cpp

#include <QCoreApplication>
#include "LinksReader.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    LinksReader linksReader;
    linksReader.run();

    return a.exec();
}

LinksReader.pro

QT        = core
QT        = network
QT       -= gui

TARGET = LinksReader
CONFIG    = console
CONFIG   -= app_bundle

TEMPLATE = app

SOURCES  = main.cpp \
    LinksReader.cpp

HEADERS  = \
    LinksReader.h

Sources.txt

http://news.google.com/news?ned=au&output=rss

http://news.google.com/news?ned=in&output=rss


http://news.google.com/news?ned=en_il&output=rss


http://news.google.com/news?ned=en_my&output=rss


http://news.google.com/news?ned=nz&output=rss


http://news.google.com/news?ned=en_pk&output=rss


http://news.google.com/news?ned=en_ph&output=rss


http://news.google.com/news?ned=en_sg&output=rss


http://news.google.com/news?ned=ar_me&output=rss


http://news.google.com/news?ned=ar_ae&output=rss


http://news.google.com/news?ned=ar_lb&output=rss


http://news.google.com/news?ned=ar_sa&output=rss


http://news.google.com/news?ned=cn&output=rss


http://news.google.com/news?ned=hk&output=rss


http://news.google.com/news?ned=hi_in&output=rss


http://news.google.com/news?ned=ta_in&output=rss


http://news.google.com/news?ned=ml_in&output=rss


http://news.google.com/news?ned=te_in&output=rss


http://news.google.com/news?ned=iw_il&output=rss


http://news.google.com/news?ned=jp&output=rss


http://news.google.com/news?ned=kr&output=rss


http://news.google.com/news?ned=tw&output=rss


http://news.google.com/news?ned=vi_vn&output=rss


http://news.google.com/news?ned=nl_be&output=rss


http://news.google.com/news?ned=fr_be&output=rss


http://news.google.com/news?ned=en_bw&output=rss


http://www.google.com/news?ned=cs_cz&output=rss


http://news.google.com/news?ned=de&output=rss


http://news.google.com/news?ned=es&output=rss


http://news.google.com/news?ned=en_et&output=rss


http://news.google.com/news?ned=fr&output=rss


http://news.google.com/news?ned=en_gh&output=rss


http://news.google.com/news?ned=en_ie&output=rss


http://news.google.com/news?ned=it&output=rss


http://news.google.com/news?ned=en_ke&output=rss


http://news.google.com/news?ned=hu_hu&output=rss


http://news.google.com/news?ned=fr_ma&output=rss


http://news.google.com/news?ned=en_na&output=rss


http://news.google.com/news?ned=nl_nl&output=rss


http://news.google.com/news?ned=en_ng&output=rss


http://news.google.com/news?ned=no_no&output=rss


http://news.google.com/news?ned=de_at&output=rss


http://news.google.com/news?ned=pl_pl&output=rss


http://news.google.com/news?ned=pt-PT_pt&output=rss


http://news.google.com/news?ned=de_ch&output=rss


http://news.google.com/news?ned=fr_sn&output=rss


http://news.google.com/news?ned=en_za&output=rss


http://news.google.com/news?ned=fr_ch&output=rss


http://news.google.com/news?ned=sv_se&output=rss


http://news.google.com/news?ned=en_tz&output=rss


http://news.google.com/news?ned=tr_tr&output=rss


http://news.google.com/news?ned=en_ug&output=rss


http://news.google.com/news?ned=uk&output=rss


http://news.google.com/news?ned=en_zw&output=rss


http://news.google.com/news?ned=ar_eg&output=rss


http://news.google.com/news?ned=el_gr&output=rss


http://news.google.com/news?ned=ru_ru&output=rss


http://news.google.com/news?ned=sr_rs&output=rss


http://news.google.com/news?ned=ru_ua&output=rss


http://news.google.com/news?ned=uk_ua&output=rss


http://news.google.com/news?ned=es_ar&output=rss


http://news.google.com/news?ned=pt-BR_br&output=rss


http://news.google.com/news?ned=ca&output=rss


http://news.google.com/news?ned=fr_ca&output=rss


http://news.google.com/news?ned=es_cl&output=rss


http://news.google.com/news?ned=es_co&output=rss


http://news.google.com/news?ned=es_cu&output=rss


http://news.google.com/news?ned=es_us&output=rss


http://news.google.com/news?ned=es_mx&output=rss


http://news.google.com/news?ned=es_pe&output=rss


http://news.google.com/news?ned=us&output=rss


http://news.google.com/news?ned=es_ve&output=rss

Позже запуска программы, создания объекта класса LinksReader и вызова его способа run происходит следующее:
1. Загружаются источники.
2. Загружаются все обнаруженные за прошлые разы RSS ссылки (Дабы не искать всякий раз по новой, а пополнять теснее имеющуюся базу RSS).
3. Проходим по каждому источником, читаем разметку и выдёргиваем все ссылки которые в разметке помечены тегом <link></link>.
4. Удаляем все повторяющиеся ссылки.
5. Проходим по каждому обнаруженным новостным сайтам, читаем разметку всякого из них и выдёргиваем значения всех RSS тегов этого сайта.
6. Удаляем все повторяющиеся RSS ссылки.
7. И наконец сберегаем итог в файл.

По эталону все RSS ссылки сайта, обязаны быть помечены тегом <link rel="alternate" type="application/rss xml" title="Моя RSS-лента" href="index.xml" />, что гораздо облегчает поиск RSS.

Как видно программа довольно примитивна, но отлично делает своё дело. За один запуск находит 600-700 RSS лент. Повторные запуски увеличивают это число, так-как в news.google.com непрерывно добавляются ссылки на новые новостные сайты.

Не хотел детально рассматривать всякую строку кода, думаю что он и так отлично читается, даже не знающим Qt. Но, если есть непонятные места — спрашивайте и я с радостью помогу разобраться. Если есть примечания, критика — пишите.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB