소스 검색

feat: 调试爬虫弹窗调整

cuiyalong 10 달 전
부모
커밋
61b17a0e26
3개의 변경된 파일211개의 추가작업 그리고 110개의 파일을 삭제
  1. 178 106
      frontend/src/components/spider/RunSpider.vue
  2. 30 0
      frontend/src/components/spider/RunSpiderDialog.vue
  3. 3 4
      frontend/src/views/CodeList.vue

+ 178 - 106
frontend/src/components/spider/RunSpider.vue

@@ -1,98 +1,111 @@
 <template>
-    <el-dialog title="仅编辑 CSS选择器部分" v-model="dialogVisible" :close-on-click-modal="false" width="80%">
-        <div class="dialog-content">
-            <div class="flex gap-2">
-                <el-space>
-                    <el-tag type="primary"> {{ formData.code }}</el-tag>
-                    <el-tag type="success"> {{ formData.site }}</el-tag>
-                    <el-tag type="info"> {{ formData.channel }}</el-tag>
-                    <el-tag type="warning">{{ formData.href }}</el-tag>
-                    <el-tag type="primary"> {{ formData.modifyuser }}</el-tag>
-                </el-space>
-            </div>
-            <div class="space"></div>
-            <el-form ref="form" :model="formData" label-width="120px">
-                <el-form-item label="URL">
-                    <el-input v-model="formData.href"></el-input>
-                </el-form-item>
-                <el-row>
-                    <el-col :span="8"><el-form-item label="列表延时(MS)">
-                            <el-input v-model="formData.listDelay"></el-input>
-                        </el-form-item></el-col>
-                    <el-col :span="8"><el-form-item label="详情延时(MS)">
-                            <el-input v-model="formData.contentDelay"></el-input>
-                        </el-form-item></el-col>
-                    <el-col :span="8"><el-form-item label="代理地址">
-                            <el-input v-model="formData.proxyServe"></el-input>
-                        </el-form-item></el-col>
-                </el-row>
-                <el-row>
-                    <el-col :span="12"><el-form-item label="浏览器">
-                            <el-radio-group v-model="formData.headless">
-                                <el-radio :value="true">无头</el-radio>
-                                <el-radio :value="false">显式</el-radio>
-                            </el-radio-group> </el-form-item>
-                    </el-col>
-                    <el-col :span="12"><el-form-item label="显示图像">
-                            <el-radio-group v-model="formData.showImage">
-                                <el-radio :value="true">显示</el-radio>
-                                <el-radio :value="false">不显示</el-radio>
-                            </el-radio-group> </el-form-item>
-                    </el-col>
-                </el-row>
+    <div class="dialog-content">
+        <div class="flex gap-2">
+            <el-space class="edit-tag-list">
+                <el-tag class="edit-tag" type="primary"> {{ formData.code }}</el-tag>
+                <el-tag class="edit-tag" type="success"> {{ formData.site }}</el-tag>
+                <el-tag class="edit-tag" type="info"> {{ formData.channel }}</el-tag>
+                <el-tag class="edit-tag" type="warning">{{ formData.href }}</el-tag>
+                <el-tag class="edit-tag" type="primary"> {{ formData.modifyuser }}</el-tag>
+            </el-space>
+        </div>
+        <div class="space"></div>
+        <el-form ref="form" :model="formData" label-width="120px">
+            <el-row>
+                <el-col :span="8">
+                    <el-form-item label="URL">
+                        <el-input v-model="formData.href" disabled :title="formData.href"></el-input>
+                    </el-form-item>
+                </el-col>
+
+                <el-col :span="8"><el-form-item label="代理地址">
+                        <el-input v-model="formData.proxyServe"></el-input>
+                    </el-form-item></el-col>
+                <el-col :span="8"><el-form-item label="最大页数">
+                        <el-input v-model="formData.maxPages"></el-input>
+                    </el-form-item></el-col>
+            </el-row>
+            <el-row>
+                <el-col :span="8"><el-form-item label="列表延时(MS)">
+                        <el-input v-model="formData.listDelay"></el-input>
+                    </el-form-item></el-col>
+                <el-col :span="8"><el-form-item label="翻页延时(MS)">
+                        <el-input v-model="formData.trunPageDelay"></el-input>
+                    </el-form-item></el-col>
+                <el-col :span="8"><el-form-item label="详情延时(MS)">
+                        <el-input v-model="formData.contentDelay"></el-input>
+                    </el-form-item></el-col>
+            </el-row>
+            <el-row>
+                <el-col :span="8"><el-form-item label="浏览器">
+                        <el-radio-group v-model="formData.headless">
+                            <el-radio :value="true">无头</el-radio>
+                            <el-radio :value="false">显式</el-radio>
+                        </el-radio-group> </el-form-item>
+                </el-col>
+                <el-col :span="8"><el-form-item label="显示图像">
+                        <el-radio-group v-model="formData.showImage">
+                            <el-radio :value="true">显示</el-radio>
+                            <el-radio :value="false">不显示</el-radio>
+                        </el-radio-group> </el-form-item>
+                </el-col>
+                <el-col :span="8"><el-form-item label="开启线程数">
+                        <el-input v-model="formData.threads"></el-input>
+                    </el-form-item></el-col>
 
-            </el-form>
-            <div style="text-align: center;">
-                <el-space>
-                    <el-button type="primary" @click="handleDebug"><el-icon>
-                            <VideoPlay />
-                        </el-icon>执行</el-button>
-                    <el-button type="primary" @click="handleStop"><el-icon>
-                            <VideoPause />
-                        </el-icon>终止</el-button>
-                    <el-button type="primary" @click="handleRefersh"><el-icon>
-                            <Refresh />
-                        </el-icon>刷新结果</el-button>
-                    <el-button type="primary" @click="handleCountYestday"><el-icon>
-                            <Refresh />
-                        </el-icon>统计昨日信息发布量</el-button>
-                    <el-dropdown>
-                        <el-button type="primary">
-                            结果导出<el-icon class="el-icon--right"><arrow-down /></el-icon>
-                        </el-button>
-                        <template #dropdown>
-                            <el-dropdown-menu>
-                                <el-dropdown-item @click="handleExportEpub">导出EPUB格式文件</el-dropdown-item>
-                                <el-dropdown-item>导出JSON格式文件</el-dropdown-item>
-                                <el-dropdown-item>导出Excel格式文件</el-dropdown-item>
-                                <el-dropdown-item>补录/上推至平台</el-dropdown-item>
-                            </el-dropdown-menu>
-                        </template>
-                    </el-dropdown></el-space>
-            </div>
-            <el-divider />
-            <div id="debugEventContian">执行日志:&nbsp;{{ debugLogLine }}</div>
-            <el-divider />
-            <el-table :data="tableData" style="width: 100%" height="240" @row-click="handleRowClick">
-                <el-table-column prop="no" label="序号" width="90" />
-                <el-table-column prop="title" label="标题" width="240" show-overflow-tooltip />
-                <el-table-column prop="href" label="链接" show-overflow-tooltip />
-                <el-table-column prop="contentShort" label="正文" show-overflow-tooltip />
-            </el-table>
+            </el-row>
+
+        </el-form>
+        <div style="text-align: center;">
+            <el-space>
+                <el-button type="primary" @click="handleDebug"><el-icon>
+                        <VideoPlay />
+                    </el-icon>执行</el-button>
+                <el-button type="primary" @click="handleStop"><el-icon>
+                        <VideoPause />
+                    </el-icon>终止</el-button>
+                <el-button type="primary" @click="handleRefersh"><el-icon>
+                        <Refresh />
+                    </el-icon>刷新结果</el-button>
+                <el-button type="primary" @click="handleCountYestday"><el-icon>
+                        <Refresh />
+                    </el-icon>统计昨日信息发布量</el-button>
+                <el-dropdown>
+                    <el-button type="primary">
+                        结果导出<el-icon class="el-icon--right"><arrow-down /></el-icon>
+                    </el-button>
+                    <template #dropdown>
+                        <el-dropdown-menu>
+                            <el-dropdown-item @click="handleExportEpub">导出EPUB格式文件</el-dropdown-item>
+                            <el-dropdown-item>导出JSON格式文件</el-dropdown-item>
+                            <el-dropdown-item @click="handleExportExcel">导出Excel格式文件</el-dropdown-item>
+                            <el-dropdown-item>补录/上推至平台</el-dropdown-item>
+                        </el-dropdown-menu>
+                    </template>
+                </el-dropdown></el-space>
         </div>
-        <ViewArticle ref="articleDialog" />
-    </el-dialog>
-    
+        <el-divider />
+        <div id="debugEventContian">执行日志:&nbsp;{{ debugLogLine }}</div>
+        <el-divider />
+        <el-table :data="tableData" style="width: 100%" :height="tableHeight" @row-click="handleRowClick">
+            <el-table-column prop="no" label="序号" width="90" />
+            <el-table-column prop="title" label="标题" width="240" show-overflow-tooltip />
+            <el-table-column prop="href" label="链接" show-overflow-tooltip />
+            <el-table-column prop="contentShort" label="正文" show-overflow-tooltip />
+        </el-table>
+    </div>
+    <ViewArticle ref="articleDialog" />
 </template>
 <script setup>
-import { ref } from 'vue';
-import { ElMessage } from 'element-plus'
+import { ref, computed } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus'
 import ViewArticle from "./ViewArticle.vue"
 
 import { ViewCurrentSpiderConfig, DebugSpider, StopDebugSpider } from "../../../wailsjs/go/main/App"
 import { ViewResultItemAll, SelectSaveFilePath, ExportEpubFile, CountYestodayArts } from "../../../wailsjs/go/main/App"
 import { EventsOn, EventsOff } from "../../../wailsjs/runtime"
 
+let originData = {}
 const formData = ref({
     // tags
     code: '',
@@ -102,36 +115,63 @@ const formData = ref({
     modifyuser: '',
 
     // form
-    listDelay: '',
-    contentDelay: '',
     proxyServe: '',
+    maxPages: '',
+    listDelay: '',
+    trunPageDelay: '',
     contentDelay: '',
     headless: false,
     showImage: false,
+    threads: '1',
+
+    cssmark: {}
 })
 
 const articleDialog = ref(null)
 
 const debugLogLine = ref("")
 const tableData = ref([])
-
-const dialogVisible = ref(false)
+const tableHeight = computed(() => window.innerHeight - 480 + 'px');
 
 const setPageData = (e) => {
-    console.log(e)
+    originData = e
+    const cssMark = e.cssmark
+    formData.value.code = e.code
+    formData.value.site = e.site
+    formData.value.channel = e.channel
+    formData.value.href = e.href
+    formData.value.modifyuser = e.modifyuser
+    if (cssMark) {
+        // form
+        formData.value.maxPages = cssMark.maxPages
+        formData.value.listDelay = cssMark.listDelayTime
+        formData.value.trunPageDelay = cssMark.listTurnDelayTime
+        formData.value.contentDelay = cssMark.contentDelayTime
+        formData.value.cssmark = cssMark
+    }
 }
-const getPageData = () => {}
 
 //开始调试
 const handleDebug = () => {
     ElMessage({
         message: `${[formData.value.url, formData.value.listDelay, formData.value.contentDelay,
-        formData.value.headless, formData.value.showImage, formData.value.proxyServe].join("//")}!`,
+        formData.value.headless, formData.value.showImage, formData.value.proxyServe, formData.value.threads,
+        formData.value.maxPages].join("//")}!`,
         showClose: true,
         duration: 3000,
     });
-    DebugSpider(formData.value.url, parseInt(formData.value.listDelay), parseInt(formData.value.contentDelay),
-        formData.value.headless == 'true', formData.value.showImage == 'true', formData.value.proxyServe)
+    DebugSpider(
+        formData.value.href,
+        formData.value.proxyServe,
+        parseInt(formData.value.maxPages),
+        parseInt(formData.value.listDelay),
+        parseInt(formData.value.trunPageDelay),
+        parseInt(formData.value.contentDelay),
+        formData.value.headless,
+        formData.value.showImage,
+        parseInt(formData.value.threads),
+        formData.value.cssmark,
+    )
 }
 //停止调试
 const handleStop = () => {
@@ -143,8 +183,8 @@ const truncateString = (str, maxLength) => {
 }
 //刷新加载数据
 const handleRefersh = () => {
-    ViewResultItemAll().then(result => {
-        result = result.slice(-20);
+    ViewResultItemAll(formData.value.code).then(result => {
+        //result = result.slice(-20);
         result.forEach((v, i) => {
             v.contentShort = truncateString(v.content, 50)
         })
@@ -153,14 +193,43 @@ const handleRefersh = () => {
 }
 //handleExportEpub导出文件
 const handleExportEpub = () => {
-    SelectSaveFilePath().then(r => {
-        if (r == "") return
-        ExportEpubFile(r).then(d => {
-            ElMessage({
-                message: `导出epub文件${r}完成!`,
-                showClose: true,
-                duration: 3000,
-            });
+    ElMessageBox.prompt('请输入书名', '书名', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+    }).then(({ value }) => {
+        SelectSaveFilePath("", value).then(save2file => {
+            if (save2file == "") {
+                console.log("无效的文件存储路径", save2file)
+                return
+            }
+            ExportEpubFile(value, save2file).then(d => {
+                ElMessage({
+                    message: `导出epub文件${save2file}完成!`,
+                    showClose: true,
+                    duration: 3000,
+                });
+            })
+        })
+    })
+}
+
+const handleExportExcel = () => {
+    ElMessageBox.prompt('请输入数据集名称', '数据集名称', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+    }).then(({ value }) => {
+        SelectSaveFilePath("", value).then(save2file => {
+            if (save2file == "") {
+                console.log("无效的文件存储路径", save2file)
+                return
+            }
+            ExportExcelFile(save2file).then(d => {
+                ElMessage({
+                    message: `导出epub文件${save2file}完成!`,
+                    showClose: true,
+                    duration: 3000,
+                });
+            })
         })
     })
 }
@@ -212,10 +281,7 @@ EventsOn("debug_event", data => {
 // })
 
 defineExpose({
-    dialogVisible,
-    formData,
     setPageData,
-    getPageData,
 })
 </script>
 <style scoped>
@@ -223,4 +289,10 @@ defineExpose({
     max-height: 60vh;
     overflow-y: scroll;
 }
+.edit-tag-list {
+    flex-wrap: wrap;
+}
+.edit-tag {
+    margin-bottom: 4px;
+}
 </style>

+ 30 - 0
frontend/src/components/spider/RunSpiderDialog.vue

@@ -0,0 +1,30 @@
+<template>
+    <el-dialog title="调试/运行" v-model="dialogVisible" :close-on-click-modal="false" width="80%">
+        <RunSpiderContent ref="runSpiderContent" />
+    </el-dialog>
+</template>
+<script setup>
+import { ref, nextTick } from 'vue';
+import RunSpiderContent from "./RunSpider.vue"
+
+const dialogVisible = ref(false)
+const runSpiderContent = ref({})
+
+const setPageData = (e) => {
+    nextTick(() => {
+        runSpiderContent.value.setPageData(e)
+    })
+}
+const getPageData = () => {
+    return runSpiderContent.value.getPageData()
+}
+
+defineExpose({
+    dialogVisible,
+    setPageData,
+    getPageData,
+})
+</script>
+<style scoped>
+
+</style>

+ 3 - 4
frontend/src/views/CodeList.vue

@@ -112,7 +112,7 @@
         </el-main>
     </el-card>
     <EditSpider ref="editSpiderDialog" @custom-event="dialogEvents.editSpiderConfigSaveEvent" />
-    <RunSpider ref="runSpiderDialog" />
+    <RunSpiderDialog ref="runSpiderDialog" />
 </template>
 
 <script setup>
@@ -121,11 +121,10 @@ import { useRouter } from 'vue-router';
 import { useStore } from 'vuex';
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { BrowserOpenURL, EventsOn } from "../../wailsjs/runtime"
-import { SaveOrUpdateSpiderConfig } from "../../wailsjs/go/main/App"
-import { SwitchSpiderConfig } from "../../wailsjs/go/main/App"
+import { SaveOrUpdateSpiderConfig, SwitchSpiderConfig } from "../../wailsjs/go/main/App"
 import Breadcrumb from "../components/Breadcrumb.vue"
 import EditSpider from "../components/spider/EditSpider.vue"
-import RunSpider from "../components/spider/RunSpider.vue"
+import RunSpiderDialog from "../components/spider/RunSpiderDialog.vue"
 import useCodeListFiltersWithRole from '../composables/filter-options'
 import { USER_ROLE_ADMIN, USER_ROLE_DEVELOPER, USER_ROLE_REVIEWER } from '../data/user'
 import { Refresh, Search, Box } from '@element-plus/icons-vue'