[LINUX] J'ai fait un simple lecteur RSS ~ Edition C ~

Certainement, un simple lecteur RSS que j'ai écrit en C il y a environ deux ans. Libcurl sous Linux, en référence à l'article [developerWorks] d'IBM (http://www.ibm.com/developerworks/jp/opensource/library/os-curl/) Il semble que j'ai appris XML en affichant le titre et la destination du lien de l'article tout en analysant le flux RSS téléchargé en utilisant / libcurl /) en utilisant libxml2. J'ai envie, mais je ne me souviens pas comment j'ai écrit le processus d'analyse XML orz

Exemple de code

Le téléchargement du flux RSS par libcurl utilise l'exemple IBM presque tel quel, et l'endroit où le résultat du téléchargement est affiché est un résumé du flux RSS d'Apple.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <errno.h>
#include <libxml/xmlerror.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>

#define MAX_BUF	65536

char wr_buf[MAX_BUF+1];
int  wr_index;

#define PATH "http://www.apple.com/jp/main/rss/hotnews/hotnews.rss"

/*
 * Write data callback function (called within the context of 
 * curl_easy_perform.
 */

size_t write_data( void *buffer, size_t size, size_t nmemb, void *userp ) {
    int segsize = size * nmemb;

    if (wr_index + segsize > MAX_BUF) {
        *(int *)userp = 1;
        return 0;
    }

    memcpy( (void *)&wr_buf[wr_index], buffer, (size_t)segsize );
    wr_index += segsize;
    wr_buf[wr_index] = 0;
    return segsize;
}

/*
 * Parse RSS and print summary.
 */

int
print_rss(char* text) {
    int     i;
    int     size;
    xmlDoc  *doc;
    xmlXPathContextPtr  xpathCtx;
    xmlXPathObjectPtr   xpathObj;
    xmlNodeSetPtr       nodes;
    xmlNode             *node;
    xmlChar             *textcount;

    /* parse an XML in-memory document and build a tree. */
    doc = xmlReadMemory(text, strlen(text), "noname.xml", NULL, 0);
    if (doc == NULL) {
        perror("xmlReadFile");
        return -1;
    }

    /* Create a new xmlXPathContext */
    xpathCtx = xmlXPathNewContext(doc);
    if (xpathCtx == NULL) {
        perror("xmlXPathNewContext");
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }

    /* Get Node list of RSS channel */
    xpathObj = xmlXPathEvalExpression(BAD_CAST "/rss/channel", xpathCtx);
    nodes = xpathObj->nodesetval;
    if (nodes == NULL) {
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }
    
    /* Get and print Title of RSS Feed. */
    size = nodes->nodeNr;
    for (i = 0; i < size; i++) {
        node = xmlFirstElementChild(nodes->nodeTab[i]);
        if (node == NULL) {
            continue;
        }
        for (; node; node = xmlNextElementSibling(node)) {
            if (strcmp((char*)node->name, "title")) {
                    continue;
            }
            textcount = xmlNodeGetContent(node);
            if (textcount) {
                printf("\nTitle: %s\n\n", textcount);
                xmlFree(textcount);
            }
        }
    }
    xmlXPathFreeObject(xpathObj);

    /* Get Node list of RSS items */
    xpathObj = xmlXPathEvalExpression(BAD_CAST "/rss/channel/item", xpathCtx);
    nodes = xpathObj->nodesetval;
    if (nodes == NULL) {
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }

    /* Get and print title and link of each items. */
    size = nodes->nodeNr;
    for (i = 0; i < size; i++) {
        node = xmlFirstElementChild(nodes->nodeTab[i]);
        if (node == NULL) {
            continue;
        }
        for (; node; node = xmlNextElementSibling(node)) {
            if (strcmp((char*)node->name, "title") != 0 &&
                strcmp((char*)node->name, "link") != 0) {
                    continue;
            }
            textcount = xmlNodeGetContent(node);
            if (textcount) {
                printf(" %s:\t%s\n", node->name, textcount);
                xmlFree(textcount);
            }
        }
        printf("\n");
    }

    xmlXPathFreeObject(xpathObj);
    xmlXPathFreeContext(xpathCtx);
    xmlFreeDoc(doc);
    xmlCleanupParser();
    return 0;
}

/*
 * Simple curl application to read the rss feed from a Web site.
 */

int main( void )
{
    CURL *curl;
    CURLcode ret;
    int  wr_error;

    wr_error = 0;
    wr_index = 0;

    curl = curl_easy_init();
    if (!curl) {
        printf("couldn't init curl\n");
        return 0;
    }

    curl_easy_setopt(curl, CURLOPT_URL, PATH);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&wr_error);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

    ret = curl_easy_perform(curl);
    if ( ret == 0 ) {
        //
        print_rss(wr_buf);
    } else {
        printf( "ret = %d (write_error = %d)\n", ret, wr_error );
        curl_easy_cleanup(curl);
        return 1;
    }

    curl_easy_cleanup(curl);
    return 0;
}

compiler

Vous avez besoin de libcurl-devel et libxml2-devel pour compiler, donc installez-les à l'avance (pour CentOS). Lors de la compilation, il est nécessaire de spécifier le fichier d'en-tête libxml2 avec l'option -I et la bibliothèque avec l'option -l.

$ cc -I/usr/include/libxml2 getrss.c -o getrss -lcurl -lxml2

Résultat d'exécution

Le résumé de "Apple-Hot News" s'affiche.

$ ./getrss

Titre: Apple-Hot News

title: Apple lance un nouveau modèle d'écran iMac Retina 5K pour 238800 yens, MacBook Pro 15 pouces avec pavé tactile sensible à la pression link: http://www.apple.com/jp/pr/library/2015/05/19Apple-Introduces-15-inch-MacBook-Pro-with-Force-Touch-Trackpad-New-1-999-iMac-with-Retina-5K-Display.html

title: Japan Post Group, IBM, Apple, les seniors japonais fournissent un iPad et une application dédiée pour se connecter avec la famille et la communauté locale via le service link: http://www.apple.com/jp/pr/library/2015/04/30Japan-Post-Group-IBM-and-Apple-Deliver-iPads-and-Custom-Apps-to-Connect-Elderly-in-Japan-to-Services-Family-and-Community.html

title: Apple annonce ses résultats du deuxième trimestre link: http://www.apple.com/jp/pr/library/2015/04/27Apple-Reports-Record-Second-Quarter-Results.html

・ ・ ・

Recommended Posts

J'ai fait un simple lecteur RSS ~ Edition C ~
Lecteur RSS simple réalisé avec Django
J'ai créé un site d'apprentissage C ++
J'ai fait un simple blackjack avec Python
〇✕ J'ai fait un jeu
J'ai fait un simple portefeuille de Bitcoin avec pycoin
J'ai fait un texte Python
J'ai fait un robot discord
J'ai créé un lecteur de flux rapide en utilisant feedparser en Python
J'ai créé une application de livre simple avec python + Flask ~ Introduction ~
J'ai fait un Line-bot avec Python!
J'ai créé un script de traduction basé sur CUI (2)
J'ai fait un wikipedia gacha bot
J'ai fait une loterie avec Python.
J'ai créé un script de traduction basé sur CUI
J'ai créé un démon avec Python
J'ai fait un circuit simple avec Python (AND, OR, NOR, etc.)
J'ai créé une caméra réseau simple en combinant ESP32-CAM et RTSP.
[Python] J'ai créé une visionneuse d'images avec une fonction de tri simple.
J'ai créé un nouveau compartiment AWS S3
J'ai créé un docset de tableau de bord pour Holoviews
J'ai fait un programme de gestion de la paie en Python!
J'ai touché "Orator" alors j'ai fait une note
J'ai fait un compteur de caractères avec Python
Débutant: j'ai créé un lanceur à l'aide d'un dictionnaire
J'ai fait une sorte d'outil de traitement d'image simple en langage Go.
J'ai fait un interlocuteur comme Siri
J'ai fait un script pour afficher des pictogrammes
J'ai fait une simple minuterie qui peut être démarrée depuis le terminal
J'ai fait une carte hexadécimale avec Python
J'ai fait un jeu de vie avec Numpy
J'ai fait un générateur Hanko avec GAN
J'ai créé un outil d'estampage automatique du navigateur.
Après avoir étudié Python3, j'ai créé un Slackbot
J'ai créé un fichier de configuration avec Python
J'ai fait une bibliothèque pour l'assurance actuarielle
J'ai fait une application WEB avec Django
J'ai fait un simulateur de neurones avec Python
[Langage C] Ma locomotive est trop lente ~ J'ai fait une commande sl ~
J'ai fait un module en langage C qui filtre les images chargées par Python
J'ai créé un fichier de dictionnaire python pour Neocomplete
J'ai fait une prévision météo de type bot avec Python.
J'ai fait un algorithme de rechange2 moins cher pour uWSGI
J'ai créé un outil utile pour Digital Ocean
J'ai créé une application graphique avec Python + PyQt5
J'ai essayé de créer un bloqueur de filles pourries sur Twitter avec Python ①
J'ai fait un truc fou appelé tuple typé
[Python] J'ai créé un téléchargeur Youtube avec Tkinter.
J'ai créé un outil de collecte de configuration de routeur Config Collecor
J'ai créé un téléchargeur pour l'expression distribuée par mot
J'ai créé un Bot LINE avec Serverless Framework!
J'ai créé un outil pour compiler nativement Hy
J'ai essayé d'ajouter un module Python 3 en C
J'ai créé un outil pour obtenir de nouveaux articles
Nous avons créé un produit de prévention du télétravail.
J'ai créé un programme cryptographique César en Python.
J'ai fait un jeu de cueillette avec Python
Made Mattermost Bot avec Python (+ Flask)
Création du wrapper d'API Qiita Python "qiipy"