1. 同步MediaCrawler为最新版本

2. 修复数据库not null错误
3. 支持PG数据库
4. 规范环境变量及配置使用
5. 规范为uv安装
6. 使用loggru
This commit is contained in:
Doiiars
2025-11-03 22:38:34 +08:00
parent 62fac9ee2e
commit f4fe4141d4
155 changed files with 9414 additions and 6247 deletions
@@ -0,0 +1,89 @@
import {defineConfig} from 'vitepress'
// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "MediaCrawler自媒体爬虫",
description: "小红书爬虫,抖音爬虫, 快手爬虫, B站爬虫, 微博爬虫,百度贴吧爬虫,知乎爬虫...。 ",
lastUpdated: true,
base: '/MediaCrawler/',
head: [
[
'script',
{async: '', src: 'https://www.googletagmanager.com/gtag/js?id=G-5TK7GF3KK1'}
],
[
'script',
{},
`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-5TK7GF3KK1');`
]
],
themeConfig: {
editLink: {
pattern: 'https://github.com/NanmiCoder/MediaCrawler/tree/main/docs/:path'
},
search: {
provider: 'local'
},
// https://vitepress.dev/reference/default-theme-config
nav: [
{text: '首页', link: '/'},
{text: '联系我', link: '/作者介绍'},
{text: '支持我', link: '/知识付费介绍'},
],
sidebar: [
{
text: '作者介绍',
link: '/作者介绍',
},
{
text: 'MediaCrawler使用文档',
items: [
{text: '基本使用', link: '/'},
{text: '常见问题汇总', link: '/常见问题'},
{text: 'IP代理使用', link: '/代理使用'},
{text: '词云图使用', link: '/词云图使用配置'},
{text: '项目目录结构', link: '/项目代码结构'},
{text: '手机号登录说明', link: '/手机号登录说明'},
]
},
{
text: '知识付费',
items: [
{text: '知识付费介绍', link: '/知识付费介绍'},
{text: 'MediaCrawlerPro订阅', link: '/mediacrawlerpro订阅'},
{
text: 'MediaCrawler源码剖析课',
link: 'https://relakkes.feishu.cn/wiki/JUgBwdhIeiSbAwkFCLkciHdAnhh'
},
{text: '知识星球文章专栏', link: '/知识星球介绍'},
{text: '开发者咨询服务', link: '/开发者咨询'},
]
},
{
text: 'MediaCrawler项目交流群',
link: '/微信交流群',
},
{
text: '爬虫入门教程分享',
items: [
{text: "我写的爬虫入门教程", link: 'https://github.com/NanmiCoder/CrawlerTutorial'}
]
},
{
text: 'MediaCrawler捐赠名单',
items: [
{text: "捐赠名单", link: '/捐赠名单'}
]
},
],
socialLinks: [
{icon: 'github', link: 'https://github.com/NanmiCoder/MediaCrawler'}
]
}
})
@@ -0,0 +1,85 @@
<!-- 在vitepress右侧的目录导航中插入动态广告组件-->
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const ads = ref([])
const currentAdIndex = ref(0)
let intervalId = null
const fetchAds = async () => {
return [
{
id: 1,
imageUrl: 'https://github.com/NanmiCoder/MediaCrawler/raw/main/docs/static/images/auto_test.png',
landingUrl: 'https://item.jd.com/10124939676219.html',
text: '给好朋友虫师新书站台推荐 - 基于Python的自动化测试框架设计'
}
]
}
const nextAd = () => {
currentAdIndex.value = (currentAdIndex.value + 1) % ads.value.length
}
onMounted(async () => {
ads.value = await fetchAds()
intervalId = setInterval(nextAd, 3000)
})
onUnmounted(() => {
if (intervalId) clearInterval(intervalId)
})
</script>
<template>
<div class="vp-ad-carousel">
<template v-if="ads.length > 0">
<div class="ad-content">
<a :href="ads[currentAdIndex].landingUrl" target="_blank" rel="noopener noreferrer">
<img :src="ads[currentAdIndex].imageUrl" :alt="ads[currentAdIndex].text" class="ad-image">
<p class="ad-text">{{ ads[currentAdIndex].text }}</p>
</a>
</div>
</template>
<p v-else class="loading">Loading ads...</p>
</div>
</template>
<style scoped>
.vp-ad-carousel {
margin-top: 1rem;
padding: 1rem;
background-color: var(--vp-c-bg-soft);
border-radius: 8px;
font-size: 0.875rem;
line-height: 1.5;
}
.ad-content {
display: flex;
flex-direction: column;
align-items: center;
}
.ad-image {
max-width: 130px;
height: auto;
margin-bottom: 0.5rem;
}
.ad-text {
text-align: center;
color: var(--vp-c-text-1);
}
.loading {
text-align: center;
color: var(--vp-c-text-2);
}
a {
text-decoration: none;
color: inherit;
}
</style>
@@ -0,0 +1,14 @@
<!--.vitepress/theme/MyLayout.vue-->
<script setup>
import DefaultTheme from 'vitepress/theme'
import DynamicAds from './DynamicAds.vue'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #aside-bottom>
<DynamicAds />
</template>
</Layout>
</template>
@@ -0,0 +1,9 @@
/* .vitepress/theme/custom.css */
/**
* Component: Sidebar
* -------------------------------------------------------------------------- */
:root {
--vp-sidebar-width: 285px;
--vp-sidebar-bg-color: var(--vp-c-bg-alt);
}
@@ -0,0 +1,9 @@
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
extends: DefaultTheme,
// 使用注入插槽的包装组件覆盖 Layout
Layout: MyLayout
}