C :: Aufgabe #136 :: Lösung #5
3 Lösungen
#136
Regelmäßiges Runterladen und Abspeichern von Dateien
Anfänger - C
von ZRX88
- 04.12.2016 um 12:06 Uhr
Eine Firma X stellt euch einen FTP Zugang (ggf. mit Zugang + PW ) zur Verfügung, wo sie jeden Tag eine Datei xyz.txt updaten und mit den aktuellsten Datensätzen befüllen.
Im ersten Schritt sollen diese Dateien heruntergeladen werden und dann auch in einem Ordner auf der Festplatte abgelegt werden.
Zum Wiedererkennen soll sowohl die Quelle als auch der Zeitpunkt des Downloads abgespeichert werden:
mögliche Beispiele:
* Zielorder > File 'FTP_x_xzy_2016_12_24.txt'
* Zielorder > Ordername '2016-12-24' > File 'xyz.txt'
Wichtig: Die Ablage muss sauber strukturiert sein.
Anmerkung: Da ich euch keinen FTP zur Verfügung stelle und wenn ihr keinen eigenen zum Testen habt:
Stattdessen ladet doch einfach den Inhalt von https://trainyourprogrammer.de/python herunter.
Optional:
* Erweitert das Programm so, dass es alle Dateien auf dem FTP herunterlädt.
* Alternativ: Speichert den Inhalt von alle verfügbaren Python Aufgaben Seiten herunter?
Im ersten Schritt sollen diese Dateien heruntergeladen werden und dann auch in einem Ordner auf der Festplatte abgelegt werden.
Zum Wiedererkennen soll sowohl die Quelle als auch der Zeitpunkt des Downloads abgespeichert werden:
mögliche Beispiele:
* Zielorder > File 'FTP_x_xzy_2016_12_24.txt'
* Zielorder > Ordername '2016-12-24' > File 'xyz.txt'
Wichtig: Die Ablage muss sauber strukturiert sein.
Anmerkung: Da ich euch keinen FTP zur Verfügung stelle und wenn ihr keinen eigenen zum Testen habt:
Stattdessen ladet doch einfach den Inhalt von https://trainyourprogrammer.de/python herunter.
Optional:
* Erweitert das Programm so, dass es alle Dateien auf dem FTP herunterlädt.
* Alternativ: Speichert den Inhalt von alle verfügbaren Python Aufgaben Seiten herunter?
#5
von devnull (8870 Punkte)
- 14.12.2016 um 13:28 Uhr
Lösung 3 lädt die Python-Aufgabentitel herunter.
Realisiert mit der libcurl via HTTPS-Protokoll.
C-Code
Realisiert mit der libcurl via HTTPS-Protokoll.
/***********************************
* pydown.c Python-Titel anzeigen
***********************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <regex.h>
#include <curl/curl.h>
#include <htmlstreamparser.h>
#define DEBUG 0
#define WEBURL "https://trainyourprogrammer.de"
#define HTTP_PROXY_HOST ""
#define HTTP_PROXY_PORT 0
#define TOPIC_NAME "python"
#define TOPIC_DESC "Python"
#define MAX_LEN 255
#define MAX_PAGES 12
#define min(x,y) ((x) < (y)) ? (x) : (y)
typedef enum _parse_state {
TOPIC_NR_SEARCH,
TOPIC_HREF_SEARCH,
TOPIC_HREF_FOUND,
TITLE_CLASS_FOUND,
TITLE_SPAN_FOUND,
TITLE_TEXT_FOUND,
FINISHED
} parse_state_t;
typedef struct _userdata {
HTMLSTREAMPARSER *hsp;
parse_state_t state;
int number;
char title[MAX_LEN+1];
} userdata_t;
/* libcurl: write callback (received data from HTTP server) */
static size_t parse_html(void *buffer, size_t size, size_t nmemb,
void *data) {
userdata_t *ud = (userdata_t *)data;
regex_t regex;
regmatch_t pm[2];
char href_part[32];
char href_pattern[32];
char topic_snum[8];
size_t realsize = size * nmemb;
size_t p, len;
int pm_len;
if (DEBUG) {
if (realsize > 0) {
fprintf(stderr, "###Data block size is %zd (%zd/%zd).\n", realsize, size, nmemb);
} else {
fprintf(stderr, "###Nothing to parse (%zd/%zd).\n", size, nmemb);
return 0;
}
}
for (p = 0; p < realsize; p++) {
html_parser_char_parse(ud->hsp, ((char *)buffer)[p]);
switch(ud->state) {
case TOPIC_NR_SEARCH:
/* Suche <div class="nr"> */
if (html_parser_cmp_tag(ud->hsp, "div", 3)) {
if (html_parser_cmp_attr(ud->hsp, "class", 5)) {
if (html_parser_is_in(ud->hsp, HTML_VALUE_ENDED)) {
html_parser_val(ud->hsp)[html_parser_val_length(ud->hsp)] = '\0';
if (strcmp(html_parser_val(ud->hsp), "nr") == 0)
ud->state = TOPIC_HREF_SEARCH;
}
}
}
break;
case TOPIC_HREF_SEARCH:
/* Suche <a href="python-135-..." */
sprintf(href_part, "%s-", TOPIC_NAME);
if (html_parser_cmp_tag(ud->hsp, "a", 1)) {
if (html_parser_cmp_attr(ud->hsp, "href", 4)) {
if (html_parser_is_in(ud->hsp, HTML_VALUE_ENDED)) {
html_parser_val(ud->hsp)[html_parser_val_length(ud->hsp)] = '\0';
if (strncmp(html_parser_val(ud->hsp), href_part, strlen(href_part)) == 0) {
if (DEBUG)
fprintf(stderr, "href-val=[%s]\n", html_parser_val(ud->hsp));
/* extract problem number */
sprintf(href_pattern, "%s-([0-9]{1,4})-", TOPIC_NAME);
if (regcomp(®ex, href_pattern, REG_EXTENDED) == 0) {
if (regexec(®ex, html_parser_val(ud->hsp), 2, pm, 0) == 0) {
if (pm[1].rm_so > 0) {
pm_len = (int)(pm[1].rm_eo - pm[1].rm_so);
sprintf(topic_snum, "%*s", pm_len, html_parser_val(ud->hsp)+pm[1].rm_so);
topic_snum[pm_len] = 0;
ud->number = atoi(topic_snum);
}
}
regfree(®ex);
}
ud->state = TOPIC_HREF_FOUND;
}
}
}
}
break;
case TOPIC_HREF_FOUND:
/* Suche <div class="title"> */
if (html_parser_cmp_tag(ud->hsp, "div", 3)) {
if (html_parser_cmp_attr(ud->hsp, "class", 5)) {
if (html_parser_is_in(ud->hsp, HTML_VALUE_ENDED)) {
html_parser_val(ud->hsp)[html_parser_val_length(ud->hsp)] = '\0';
if (strcmp(html_parser_val(ud->hsp), "title") == 0)
ud->state = TITLE_CLASS_FOUND;
}
}
}
break;
case TITLE_CLASS_FOUND:
/* Suche <span>Titeltext</span> */
if (html_parser_cmp_tag(ud->hsp, "span", 4))
ud->state = TITLE_SPAN_FOUND;
break;
case TITLE_SPAN_FOUND:
/* extrahiere Aufgabentitel */
if ((len = html_parser_inner_text_length(ud->hsp)) > 0) {
len = min(len, MAX_LEN);
strncpy(ud->title, html_parser_inner_text(ud->hsp), len);
ud->title[len] = '\0';
if (len > 0)
printf("Titel #%-3d : \"%s\"\n", ud->number, ud->title);
ud->state = TITLE_TEXT_FOUND;
}
break;
case TITLE_TEXT_FOUND:
/* Status-Reset oder Ende */
ud->state = (ud->number > 1) ? TOPIC_NR_SEARCH : FINISHED;
break;
default:
ud->state = FINISHED;
}
}
return realsize;
}
int main(int argc, char *argv[])
{
CURL *curl;
CURLcode curl_res;
userdata_t ud;
HTMLSTREAMPARSER *hsp;
char url[MAX_LEN+1]; /* URL string */
char text[MAX_LEN+1]; /* html inner text (title) */
char val[128]; /* attribute value */
char attr[6]; /* attribute name */
char tag[6]; /* tag name */
int page;
char errbuf[MAX_LEN+1]; /* curl error buffer */
size_t errlen;
/* init HTML stream parser */
if ((hsp = html_parser_init()) != NULL) {
html_parser_set_tag_to_lower(hsp, 1);
html_parser_set_attr_to_lower(hsp, 1);
html_parser_set_tag_buffer(hsp, tag, sizeof(tag));
html_parser_set_attr_buffer(hsp, attr, sizeof(attr));
html_parser_set_val_buffer(hsp, val, sizeof(val)-1);
html_parser_set_inner_text_buffer(hsp, text, sizeof(text)-1);
}
else {
fprintf(stderr, "Cannot initialize html stream parser.\n");
return EXIT_FAILURE;
}
/* init user data struct */
ud.number = -1;
ud.title[0] = '\0';
ud.hsp = hsp;
/* init libcurl */
if ((curl = curl_easy_init()) != NULL) {
if (strlen(HTTP_PROXY_HOST) > 0) {
curl_easy_setopt(curl, CURLOPT_PROXY, HTTP_PROXY_HOST);
if (HTTP_PROXY_PORT > 0)
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (long)HTTP_PROXY_PORT);
}
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, parse_html);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ud);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
}
else {
fprintf(stderr, "Cannot initialize curl lib.\n");
return EXIT_FAILURE;
}
/* browse the pages on the web site */
for (page=1; page <= MAX_PAGES; page++) {
printf("\nAufgaben auf der %s-Seite %d:\n\n", TOPIC_DESC, page);
sprintf(url, "%s/index.pl?page=%s&seite=%d", WEBURL, TOPIC_NAME, page);
curl_easy_setopt(curl, CURLOPT_URL, url);
ud.state = TOPIC_HREF_SEARCH;
if ((curl_res = curl_easy_perform(curl)) != CURLE_OK) {
errlen = strlen(errbuf);
fprintf(stderr, "\nlibcurl: (%d) ", curl_res);
fprintf(stderr, "%s\n", (errlen)?errbuf:curl_easy_strerror(curl_res));
break;
}
if (ud.state == FINISHED)
break;
}
/* cleanup */
curl_easy_cleanup(curl);
html_parser_cleanup(hsp);
return 0;
}
Kommentare:
Für diese Lösung gibt es noch keinen Kommentar
Seite 1 von 0
1
