Вызвать веб-страницу из Linux C - PullRequest
2 голосов
/ 05 мая 2010

Мне нужно прочитать весь текст HTML с URL-адреса типа http://localhost/index.html в строку в C.

Я знаю, что если я надену telnet -> telnet www.google.com 80 Get webpage...., он вернет все html.

Как мне сделать это в среде Linux с C?

Ответы [ 5 ]

6 голосов
/ 05 мая 2010

Я бы предложил использовать пару библиотек, которые обычно доступны в большинстве дистрибутивов Linux:

libcurl и libxml2

libcurl предоставляет полный набор функций http, а libxml2 предоставляет модуль для анализа html, который называется HTMLParser

Надеюсь, это укажет вам правильное направление

3 голосов
/ 05 мая 2010

Ниже приведен примерный набросок кода (т. Е. Не слишком много ошибок, и я не пытался его скомпилировать), чтобы начать, но используйте http://www.tenouk.com/cnlinuxsockettutorials.html для изучения программирования сокетов. Найдите gethostbyname, если вам нужно перевести имя хоста (например, google.com) в IP-адрес. Также вам может потребоваться проделать определенную работу, чтобы проанализировать длину содержимого из ответа HTTP, а затем убедиться, что вы продолжаете вызывать recv, пока не получите все байты.

#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>

void getWebpage(char *buffer, int bufsize, char *ipaddress)
{
    int sockfd;
    struct sockaddr_in destAddr;

    if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){
        fprintf(stderr, "Error opening client socket\n");
        close(sockfd);
        return;
    }

    destAddr.sin_family = PF_INET;
    destAddr.sin_port = htons(80); // HTTP port is 80
    destAddr.sin_addr.s_addr = inet_addr(ipaddress); // Get int representation of IP
    memset(&(destAddr.sin_zero), 0, 8);

    if(connect(sockfd, (struct sockaddr *)&destAddr, sizeof(struct sockaddr)) == -1){
        fprintf(stderr, "Error with client connecting to server\n");
        close(sockfd);
        return;
    }

    // Send http request
    char *httprequest = "GET / HTTP/1.0";
    send(sockfd, httprequest, strlen(httprequest), 0);
    recv(sockfd, buffer, bufsize, 0);

    // Now buffer has the HTTP response which includes the webpage. You can either
    // trim off the HTTP header, or just leave it in depending on what you are doing
    // with the page
}
1 голос
/ 05 мая 2010

Если вы действительно не хотите возиться с сокетами, вы всегда можете создать именованный временный файл, отключить процесс и выполнить execvp () для запуска wget -0, а затем прочитать ввод из этого временного файла.

хотя это был бы довольно неэффективный и неэффективный способ сделать что-то, это означало бы, что вам не придется связываться с TCP и отправкой HTTP-запросов.

1 голос
/ 05 мая 2010

Вы используете сокеты, опрашиваете веб-сервер по HTTP (где у вас есть "http://localhost/index.html"), а затем анализируете полученные данные.

Полезно, если вы новичок в программировании сокетов: http://beej.us/guide/bgnet/

0 голосов
/ 05 мая 2010

Если вы знаете, как прочитать файл в строку, я бы попробовал

const char *url_contents(const char *url) {
  // create w3m command and pass it to popen()
  int bufsize = strlen(url) + 100;
  char *buf = malloc(bufsize);
  snprintf(buf, bufsize, "w3m -dump_source '%s'");

  // get a file handle, read all the html from it, close, and return
  FILE *html = popen(buf, "r");
  const char *s = read_file_into_string(html); // you write this function
  fclose(html);
  return s;
}

Вы запускаете процесс, но намного проще позволить w3m выполнять тяжелую работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...