c 提取网页表格数据库

提取网页表格数据库通常涉及使用编程语言(如Python)和库(如BeautifulSoup或Scrapy)来解析HTML并提取所需数据。

在现代Web开发中,提取网页中的表格数据并将其存储到数据库是一项常见且重要的任务,这一过程通常涉及多个步骤,包括抓取网页内容、解析HTML表格、处理数据以及将数据插入到数据库中,以下是一个详细的指南,介绍如何使用C语言完成这一任务。

c 提取网页表格数据库

准备工作

1 环境配置

安装必要的库:为了简化HTTP请求和HTML解析,可以使用libcurl库进行HTTP请求,使用libxml2库解析HTML。

设置编译器:确保你的系统上安装了GCC或其他支持的C编译器。

2 创建项目结构

项目目录:创建一个项目目录,例如web_table_extractor

文件结构:在项目目录下创建以下文件:

main.c:主程序入口。

http_request.chttp_request.h:处理HTTP请求。

html_parser.chtml_parser.h:解析HTML并提取表格数据。

c 提取网页表格数据库

database.cdatabase.h:处理数据库连接和数据插入。

实现HTTP请求

1 编写HTTP请求模块

http_request.c

#include "http_request.h"
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t write_callback(void ptr, size_t size, size_t nmemb, void stream) {
    size_t real_size = size  nmemb;
    charresponse = (char)stream;
    response = realloc(response, strlen(response) + real_size + 1);
    memcpy(response + strlen(response), ptr, real_size);
    (response)[strlen(response) + real_size] = '';
    return real_size;
}
char fetch_url(const char url) {
    CURL curl;
    CURLcode res;
    char response = NULL;
    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s
", curl_easy_strerror(res));
            free(response);
            response = NULL;
        }
        curl_easy_cleanup(curl);
    }
    return response;
}

http_request.h

#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H
char fetch_url(const char url);
#endif // HTTP_REQUEST_H

解析HTML表格

1 编写HTML解析模块

html_parser.c

#include "html_parser.h"
#include <libxml/HTMLparser.h>
#include <libxml/xpath.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
    char data;
    size_t rows;
    size_t cols;
} TableData;
TableData parse_html_table(const char html) {
    htmlDocPtr doc = htmlReadMemory(html, strlen(html), NULL, NULL, HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
    if(!doc) {
        fprintf(stderr, "Failed to parse HTML document
");
        exit(EXIT_FAILURE);
    }
    xmlXPathContextPtr context = xmlXPathNewContext(doc);
    if(!context) {
        fprintf(stderr, "Failed to create XPath context
");
        exit(EXIT_FAILURE);
    }
    xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar )"//table", context);
    if(!result || !result->nodesetval || result->nodesetval->nodeNr == 0) {
        fprintf(stderr, "No table found in HTML
");
        exit(EXIT_FAILURE);
    }
    xmlNodeSetPtr nodes = result->nodesetval;
    xmlNodePtr table = nodes->nodeTab[0];
    xmlNodePtr row = NULL;
    xmlNodePtr cell = NULL;
    TableData tableData = {NULL, 0, 0};
    size_t rowCount = 0;
    size_t colCount = 0;
    for(row = table->children; row; row = row->next) {
        if(row->type == XML_ELEMENT_NODE && !xmlStrcmp(row->name, (const xmlChar )"tr")) {
            if(tableData.rows == 0) {
                for(cell = row->children; cell; cell = cell->next) {
                    if(cell->type == XML_ELEMENT_NODE && !xmlStrcmp(cell->name, (const xmlChar )"td")) {
                        colCount++;
                    }
                }
                tableData.cols = colCount;
                tableData.data = malloc(sizeof(char )  colCount  rowCount);
            }
            size_t cellIndex = 0;
            for(cell = row->children; cell; cell = cell->next) {
                if(cell->type == XML_ELEMENT_NODE && !xmlStrcmp(cell->name, (const xmlChar )"td")) {
                    xmlChar content = xmlNodeGetContent(cell);
                    tableData.data[rowCount  colCount + cellIndex] = strdup((const char )content);
                    xmlFree(content);
                    cellIndex++;
                }
            }
            rowCount++;
        }
    }
    tableData.rows = rowCount;
    xmlXPathFreeObject(result);
    xmlXPathFreeContext(context);
    xmlFreeDoc(doc);
    xmlCleanupParser();
    return tableData;
}

html_parser.h

#ifndef HTML_PARSER_H
#define HTML_PARSER_H
typedef struct {
    char data;
    size_t rows;
    size_t cols;
} TableData;
TableData parse_html_table(const char html);
#endif // HTML_PARSER_H

数据库操作

1 编写数据库模块

database.c

#include "database.h"
#include <mysql/mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
MYSQL connect_db() {
    MYSQL conn = mysql_init(NULL);
    if(conn == NULL) {
        fprintf(stderr, "MySQL initialization failed
");
        return NULL;
    }
    if(!mysql_real_connect(conn, "localhost", "user", "password", "database", 0, NULL, 0)) {
        fprintf(stderr, "Failed to connect to database: Error: %s
", mysql_error(conn));
        mysql_close(conn);
        return NULL;
    }
    return conn;
}
void insert_table_data(MYSQL conn, TableData data) {
    char query[1024];
    snprintf(query, sizeof(query), "INSERT INTO table_data (column1, column2, ...) VALUES ");
    for(size_t i = 0; i < data.rows; i++) {
        strcat(query, "(");
        for(size_t j = 0; j < data.cols; j++) {
            char value[256];
            snprintf(value, sizeof(value), "'%s'", data.data[i  data.cols + j]);
            strcat(query, value);
            if(j < data.cols 1) strcat(query, ", ");
        }
        strcat(query, "), ");
    }
    query[strlen(query) 2] = ''; // Remove trailing comma and space
    if(mysql_query(conn, query)) {
        fprintf(stderr, "Failed to insert data: Error: %s
", mysql_error(conn));
    } else {
        printf("Data inserted successfully
");
    }
}

database.h

c 提取网页表格数据库

#ifndef DATABASE_H
#define DATABASE_H
#include <mysql/mysql.h>
#include "table_data.h"
MYSQL connect_db();
void insert_table_data(MYSQL conn, TableData data);
#endif // DATABASE_H

主程序整合

main.c

#include "http_request.h"
#include "html_parser.h"
#include "database.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
int main() {
    const char url = "http://example.com/page"; // 替换为实际的网页URL
    char html = fetch_url(url);
    if(!html) {
        fprintf(stderr, "Failed to fetch URL content
");
        return EXIT_FAILURE;
    }
    TableData tableData = parse_html_table(html);
    free(html); // 释放HTTP请求获取的内存
    MYSQL conn = connect_db();
    if(!conn) {
        fprintf(stderr, "Failed to connect to database
");
        return EXIT_FAILURE;
    }
    insert_table_data(conn, tableData);
    mysql_close(conn); // 关闭数据库连接
    for(size_t i = 0; i < tableData.rows; i++) {
        for(size_t j = 0; j < tableData.cols; j++) {
            free(tableData.data[i  tableData.cols + j]); // 释放解析后的表格数据内存
        }
    }
    free(tableData.data); // 释放表格数据指针数组内存
    return EXIT_SUCCESS;
}

编译与运行

确保安装了libcurl、libxml2和MySQL开发库后,使用以下命令编译:

gcc -o web_table_extractor main.c http_request.c html_parser.c database.c -lcurl -lxml2 -lmysqlclient -lm -lpthread

然后运行程序:

./web_table_extractor

如果一切正常,程序将从指定的URL抓取网页,解析其中的表格数据,并将其插入到MySQL数据库中。

FAQs(常见问题解答)

Q1: 如果网页结构发生变化,如何调整代码以适应新的结构?

A1: 如果网页结构发生变化,需要更新parse_html_table函数中的XPath表达式以匹配新的表格结构,如果表格的XPath从//table变为//div[@id='new-table']/table,则需要相应地修改代码,确保解析逻辑能够正确处理新的单元格和行结构,如果表格的列数或格式发生变化,也需要调整insert_table_data函数中的SQL查询语句,以确保数据正确插入数据库,建议定期检查和维护代码,以应对可能的结构变化。

原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1657819.html

本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。

(0)
未希未希
上一篇2025-03-20 16:58
下一篇 2025-03-20 17:01

发表回复

您的电子邮箱地址不会被公开。必填项已用 * 标注

产品购买QQ咨询微信咨询SEO优化
分享本页
返回顶部
云产品限时秒杀。精选云产品高防服务器,20M大带宽限量抢购  >>点击进入