摘要
以下内容来自gpt-4o-2024-08-13,提问“HackTips是什么意思”
“HackTips”是指与黑客、编程技巧、技术提示相关的信息或指南。通常,它涉及如何使用技术、工具或程序提高效率、解决问题,或者帮助用户掌握一些特定领域的知识。这些提示可能涵盖广泛的内容,比如安全建议、代码优化、自动化脚本等。
正文
POC入库
<?php
// 定义一个关键词数组,用于在 GitHub API 中搜索相关仓库
$keywords = ['CVE-2020', 'CVE-2021', 'CVE-2022', 'CVE-2023', 'CVE-2024', 'CNVD-'];
// GitHub API 访问令牌
$accessToken = 'YOU_ARE_GITHUB_KEY';
// 数据库连接信息
$dsn = 'mysql:host=localhost;dbname=root;charset=utf8'; // 数据源名称
$username = 'root'; // 数据库用户名
$password = '123456'; // 数据库密码
// 创建 PDO 实例用于数据库操作
$pdo = new PDO($dsn, $username, $password);
// 初始化成功和错误计数
$successCount = 0; // 成功插入的记录数
$errorCount = 0; // 发生的错误数
// 遍历每个关键词进行搜索
foreach ($keywords as $keyword) {
// 对每个关键词进行分页搜索,最多 50 页
for ($page = 1; $page <= 50; $page++) {
// 构造 GitHub API 搜索 URL
$url = "https://api.github.com/search/repositories?q=" . urlencode($keyword) . "&per_page=100&page=$page";
// 设置 HTTP 请求头,包括 User-Agent 和授权头
$options = [
"http" => [
"header" => "User-Agent: My PHP Script\r\n" . // GitHub API 要求提供 User-Agent
"Authorization: Bearer $accessToken" // 添加授权令牌
]
];
// 创建 HTTP 上下文
$context = stream_context_create($options);
// 发送请求以获取数据
$response = file_get_contents($url, false, $context);
// 检查响应是否成功
if ($response === false) {
echo "错误:无法从 GitHub API 获取数据,关键词:$keyword\n"; // 输出错误信息
$errorCount++; // 错误计数加一
continue; // 跳过当前循环
}
// 将 JSON 响应解析为数组
$result = json_decode($response, true);
// 检查是否找到搜索结果
if (isset($result['items'])) {
foreach ($result['items'] as $item) {
// 获取仓库的 HTML URL
$repoUrl = $item['html_url'];
// 检查数据库中是否已经存在相同的仓库地址
$stmt = $pdo->prepare("SELECT COUNT(*) FROM github_monitor WHERE repo_url = ?");
$stmt->execute([$repoUrl]); // 执行查询语句
$existingCount = $stmt->fetchColumn(); // 获取已有记录数
// 如果仓库地址已存在,跳过插入操作
if ($existingCount > 0) {
echo "已存在相同的仓库地址:$repoUrl,跳过插入操作\n"; // 输出信息
continue; // 跳过当前循环
}
// 获取仓库名称、描述和创建时间
$repoName = $item['full_name'];
$description = $item['description'];
$createdAt = date('Y-m-d H:i:s', strtotime($item['created_at'])); // 格式化创建时间
// 插入仓库信息到数据库
$stmt = $pdo->prepare("INSERT INTO github_monitor (repo_name, repo_url, description, created_at) VALUES (?, ?, ?, ?)");
$result = $stmt->execute([$repoName, $repoUrl, $description, $createdAt]); // 执行插入操作
// 检查插入操作是否成功
if ($result) {
echo "已插入仓库:$repoName\n"; // 输出成功信息
$successCount++; // 成功计数加一
} else {
echo "错误:插入仓库失败:$repoName\n"; // 输出失败信息
$errorCount++; // 错误计数加一
}
}
} else {
echo "警告:未找到关键词:$keyword 的结果\n"; // 输出未找到结果的警告
$errorCount++; // 错误计数加一
}
// 如果结果少于 100 条,则已获取所有结果,结束分页
if (count($result['items']) < 100) {
break; // 退出分页循环
}
}
}
// 输出总结信息
echo "总共成功插入的仓库数:$successCount\n"; // 输出成功插入的总数
echo "遇到的错误总数:$errorCount\n"; // 输出遇到的错误总数
?>
Rss入库
// 获取数据库中的 URL
$sql = "SELECT `url` FROM `Rssapi`";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$batchSize = 50; // 每批处理的数量
$urls = [];
// 将 URL 存入数组,并排除包含非预期字符的 URL
while ($row = $result->fetch_assoc()) {
$url = trim($row['url']);
if (strpos($url, 'NULL') === false) { // 排除包含 'NULL' 的 URL
$urls[] = $url;
}
}
// 调试输出:输出 $urls 数组的内容和长度
echo "urls 数组长度:" . count($urls) . "<br>";
var_dump($urls);
// 分批处理 URL
for ($i = 0; $i < count($urls); $i += $batchSize) {
$batchUrls = array_slice($urls, $i, $batchSize);
// 调试输出:输出起始索引和切片长度的值,以及每次迭代中提取的 $batchUrls 数组的值
echo "起始索引: $i, 切片长度: $batchSize<br>";
var_dump($batchUrls);
// 添加条件检查以确保数组不为空
if (!empty($batchUrls)) {
processUrls($batchUrls, $conn);
} else {
echo "警告:$batchUrls 变量为空。<br>";
}
}
echo "数据导入成功!";
} else {
echo "暂未提交";
}
// 关闭数据库连接
$conn->close();
// 处理 URL
function processUrls($urls, $conn) {
foreach ($urls as $url) {
echo "正在处理 URL: $url<br>";
try {
// 尝试加载 XML 文件
$xml = simplexml_load_file($url);
if ($xml === false) {
throw new Exception("加载文件失败: " . libxml_get_last_error());
}
// 自动识别 RSS 格式并解析
if (isset($xml->channel)) { // RSS 2.0
parseRSS2($xml, $conn);
} elseif (isset($xml->entry)) { // Atom
parseAtom($xml, $conn);
} elseif (isset($xml->item)) { // RSS 1.0
parseRSS1($xml, $conn);
} else {
echo "未知的 RSS 格式。<br>";
}
} catch (Exception $e) {
// 发生异常,输出错误信息并跳过当前URL
echo "发生异常: " . $e->getMessage() . "<br>";
continue;
}
}
}
// 解析 RSS 2.0
function parseRSS2($xml, $conn) {
foreach ($xml->channel->item as $item) {
// 解析每个条目并插入数据库
$title = (string) $item->title;
$link = (string) $item->link;
$description = (string) $item->description;
$author = (string) $item->author;
$category = (string) $item->category;
$pubDate = (string) $item->pubDate;
// 插入数据到数据库
insertData($conn, $title, $link, $description, $author, $category, $pubDate);
}
}
// 解析 Atom
function parseAtom($xml, $conn) {
foreach ($xml->entry as $entry) {
// 解析每个条目并插入数据库
$title = (string) $entry->title;
$link = (string) $entry->link['href'];
$content = (string) $entry->content;
$author = (string) $entry->author->name;
$pubDate = (string) $entry->published;
// 插入数据到数据库
insertData($conn, $title, $link, $content, $author, '', $pubDate);
}
}
// 解析 RSS 1.0
function parseRSS1($xml, $conn) {
foreach ($xml->item as $item) {
// 解析每个条目并插入数据库
$title = (string) $item->title;
$link = (string) $item->link;
$description = (string) $item->description;
$pubDate = (string) $item->pubDate;
// 插入数据到数据库
insertData($conn, $title, $link, $description, '', '', $pubDate);
}
}
// 插入数据到数据库
function insertData($conn, $title, $link, $description, $author, $category, $pubDate) {
// 检查数据库中是否已存在相同的链接
$link = $conn->real_escape_string($link); // 转义字符串以防止 SQL 注入
$sql_check = "SELECT * FROM `data` WHERE `link`='$link'";
$result = $conn->query($sql_check);
if ($result->num_rows == 0) {
// 如果数据库中不存在相同的链接,则将数据添加到数组中
$sql = "INSERT INTO `data` (`title`, `link`, `description`, `author`, `category`, `pubDate`) VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
if ($stmt === false) {
echo "SQL 准备失败: " . $conn->error;
return;
}
$stmt->bind_param("ssssss", $title, $link, $description, $author, $category, $pubDate);
if ($stmt->execute() === false) {
echo "插入数据失败: " . $stmt->error;
echo "失败的链接: " . $link . "<br>"; // 记录失败的链接
}
}
}