[LINUX] Ich habe einen einfachen RSS-Reader ~ C Edition ~ gemacht

Sicherlich ein einfacher RSS-Reader, den ich vor ein paar Jahren in C geschrieben habe. Libcurl unter Linux unter Bezugnahme auf den Artikel über IBMs developerWorks Es scheint, dass ich XML gelernt habe, indem ich den Titel und das Linkziel des Artikels angezeigt habe, während ich den mit / libcurl /) heruntergeladenen RSS-Feed mit libxml2 analysiert habe. Ich habe Lust, aber ich kann mich nicht erinnern, wie ich den XML-Analyseprozess orz geschrieben habe

Beispielcode

Beim Herunterladen des RSS-Feeds durch libcurl wird das IBM-Beispiel fast unverändert verwendet. Der Ort, an dem das Download-Ergebnis angezeigt wird, ist eine Zusammenfassung des RSS-Feeds von 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;
}

kompilieren

Zum Kompilieren benötigen Sie libcurl-devel und libxml2-devel. Installieren Sie sie daher im Voraus (für CentOS). Zur Kompilierungszeit muss die Headerdatei libxml2 mit der Option -I und die Bibliothek mit der Option -l angegeben werden.

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

Ausführungsergebnis

Die Zusammenfassung von "Apple-Hot News" wird angezeigt.

$ ./getrss

Titel: Apple-Hot News

Titel: Apple bringt neues iMac Retina 5K-Displaymodell für 238.800 Yen, 15-Zoll-MacBook Pro mit druckempfindlichem Touch-Track-Pad auf den Markt 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

Titel: Japan Post Group, IBM, Apple, japanische Senioren bieten iPad und spezielle Anwendungen an, um über Service eine Verbindung zur Familie und zur lokalen Gemeinschaft herzustellen 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

Titel: Apple gibt Ergebnisse des zweiten Quartals bekannt link: http://www.apple.com/jp/pr/library/2015/04/27Apple-Reports-Record-Second-Quarter-Results.html

・ ・ ・

Recommended Posts

Ich habe einen einfachen RSS-Reader ~ C Edition ~ gemacht
Einfacher RSS-Reader mit Django
Ich habe eine C ++ - Lernseite erstellt
Ich habe mit Python einen einfachen Blackjack gemacht
〇✕ Ich habe ein Spiel gemacht
Ich habe eine einfache Brieftasche aus Bitcoin mit Pycoin gemacht
Ich habe einen Python-Text gemacht
Ich habe einen Zwietrachtbot gemacht
Ich habe einen schnellen Feed-Reader mit Feedparser in Python erstellt
Ich habe eine einfache Buch-App mit Python + Flask ~ Introduction ~ erstellt
Ich habe einen Line-Bot mit Python gemacht!
Ich habe ein CUI-basiertes Übersetzungsskript erstellt (2)
Ich habe einen Wikipedia Gacha Bot gemacht
Ich habe mit Python eine Lotterie gemacht.
Ich habe ein CUI-basiertes Übersetzungsskript erstellt
Ich habe mit Python einen Daemon erstellt
Ich habe eine einfache Schaltung mit Python gemacht (AND, OR, NOR, etc.)
Ich habe eine einfache Netzwerkkamera hergestellt, indem ich ESP32-CAM und RTSP kombiniert habe.
[Python] Ich habe einen Bildbetrachter mit einer einfachen Sortierfunktion erstellt.
Ich habe einen neuen AWS S3-Eimer hergestellt
Ich habe ein Dash-Docset für Holoviews erstellt
Ich habe ein Pay-Management-Programm in Python erstellt!
Ich berührte "Orator" und machte mir eine Notiz
Ich habe mit Python einen Zeichenzähler erstellt
Anfänger: Ich habe einen Launcher mit dem Wörterbuch erstellt
Ich habe eine Art einfaches Bildverarbeitungswerkzeug in der Sprache Go erstellt.
Ich habe einen Gesprächspartner wie Siri gemacht
Ich habe ein Skript erstellt, um Piktogramme anzuzeigen
Ich habe einen einfachen Timer erstellt, der vom Terminal aus gestartet werden kann
Ich habe mit Python eine Hex-Map erstellt
Ich habe ein Lebensspiel mit Numpy gemacht
Ich habe einen Hanko-Generator mit GAN gemacht
Ich habe ein automatisches Stempelwerkzeug für den Browser erstellt.
Nachdem ich Python3 studiert hatte, machte ich einen Slackbot
Ich habe mit Python eine Einstellungsdatei erstellt
Ich habe eine Bibliothek für versicherungsmathematische Versicherungen erstellt
Ich habe eine WEB-Bewerbung bei Django gemacht
Ich habe mit Python einen Neuronensimulator erstellt
[C Sprache] Meine Lokomotive ist zu langsam ~ Ich habe einen Sl-Befehl gegeben ~
Ich habe ein Modul in C-Sprache erstellt, das von Python geladene Bilder filtert
Ich habe eine Python-Wörterbuchdatei für Neocomplete erstellt
Ich habe mit Python eine Bot-Wettervorhersage gemacht.
Ich habe einen Ersatz2-Algorithmus für uWSGI billiger gemacht
Ich habe ein nützliches Tool für Digital Ocean erstellt
Ich habe eine GUI-App mit Python + PyQt5 erstellt
Ich habe versucht, mit Python einen Twitter-Blocker für faule Mädchen zu machen
Ich habe ein verrücktes Ding namens getipptes Tupel gemacht
[Python] Ich habe mit Tkinter einen Youtube Downloader erstellt.
Ich habe ein Router-Konfigurationssammlungstool Config Collecor erstellt
Ich habe einen Downloader für wortverteilte Ausdrücke erstellt
Ich habe einen LINE Bot mit Serverless Framework erstellt!
Ich habe ein Tool erstellt, um Hy nativ zu kompilieren
Ich habe versucht, ein Python 3-Modul in C hinzuzufügen
Ich habe ein Tool erstellt, um neue Artikel zu erhalten
Wir haben ein Peeping-Prevention-Produkt für die Telearbeit entwickelt.
Ich habe ein Caesar-Kryptografieprogramm in Python erstellt.
Ich habe mit Python ein Bin-Picking-Spiel gemacht
Mattermost Bot mit Python gemacht (+ Flask)
Python Qiita API Wrapper "qiipy" gemacht