Total Pageviews

Saturday 1 April 2023

历史上的今天

 事实上,在 Mac 上就自带了一个小型的「历史上的今天」数据库,执行:

cat /usr/share/calendar/calendar.history

就可以看到


这篇文章将介绍如何搭建一个提供「历史上的今天」信息的 API。

建立数据库

首先,建立 MySQL 数据库和数据表,用于存储爬取的信息。这里数据库和数据表名都以 event 为例。

CREATE DATABASE event;
USE event;
CREATE TABLE event (
id int(10) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
type int(1) DEFAULT NULL,
year varchar(6) DEFAULT NULL,
date varchar(6) DEFAULT NULL,
info text DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
QUIT;

获取数据

数据来源是维基百科,使用 Python 爬取数据,并存入数据库中。项目地址:https://github.com/stevenjoezhang/TodayInHistory-Crawler,可以打包下载所有文件。

下载程序源码后,进入目录并安装依赖:

pip3 install -r requirements.txt

config.py 中的 usernamepassworddbnametablename 分别是你的登录用户名、密码、数据库名和数据表名。将它们修改成和之前创建的数据库和数据表名一致。

然后,运行 spider.py,程序将会开始爬取数据。程序会用 try except 处理特殊字符(非 UTF-8 范围)的问题,并将失败的项目记录在 failed.txt 中。

查询数据

比较简单的方式是按照 json 格式进行输出,server.py 给出了一种使用 Python 的方案,运行后就可以访问 Flask 创建的服务器了。

当然,用 PHP 也是可以实现的,毕竟只需要进行 MySQL 查询,没有静态文件,很方便。可以使用如下代码:

<?php
$mysqli = new mysqli("localhost", "username", "password", "dbname");

/* 检查连接 */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}

$date = $_GET['date'] ? $mysqli->real_escape_string($_GET['date']) : date("m月d日");
$type = $_GET['type'] ? (int)$mysqli->real_escape_string($_GET['type']) : 0;
$count = $_GET['count'] ? (int)$mysqli->real_escape_string($_GET['count']) : 1;
$result = array();

/* 创建一个预编译 SQL 语句 */
if ($stmt = $mysqli->prepare("select * from `event` where `date` = ? and `type` = ? order by RAND() limit ?")) {
/* 对于参数占位符进行参数值绑定 */
$stmt->bind_param("dii", $date, $type, $count);
/* 执行查询 */
$stmt->execute();
/* 将查询结果绑定到变量 */
$stmt->bind_result($id, $type, $year, $date, $info);
/* 获取查询结果值 */
while ($stmt->fetch()) {
$arr = array('year' => $year, 'info' => $info);
$result[] = $arr;
};
echo json_encode($result, JSON_UNESCAPED_UNICODE);
/* 关闭语句句柄 */
$stmt->close();
}
/* 关闭连接 */
$mysqli->close();
?>

利用维基百科的导出页面功能,可以一次性获取所有日期的文本,通过解析 XML 文件也能将内容存入数据库中。

No comments:

Post a Comment