123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <template>
- <ContentWrap>
- <el-form
- class="-mb-15px"
- :model="queryParams"
- ref="queryFormRef"
- :inline="true"
- label-width="90px"
- >
- <el-form-item label="url抓取数据" prop="urls">
- <el-input
- v-model="queryParams.urls"
- class="!w-420px"
- type="textarea"
- :rows="1"
- placeholder="请输入需要爬取的页面,多个页面请用 ',' 隔开"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" plain :loading="loading" @click="handleExecute">执行</el-button>
- </el-form-item>
- </el-form>
- </ContentWrap>
- <ContentWrap v-if="contents.length">
- <el-row gutter="20">
- <el-col v-for="(content, index) in contents" :key="index" :span="12">
- <el-card class="!h-500px" v-loading="!content.data">
- <template #header>
- <div class="flex items-center justify-between">
- <el-text class="flex-1" truncated>{{ content.url }}</el-text>
- <div class="!w-85px">
- <Icon icon="ep:view" size="25" class="ml-10px cursor-pointer" color="#409eff" @click="showPage(content)" />
- <Icon icon="ep:refresh" size="25" class=" ml-18px cursor-pointer" color="#409eff" @click="handleReload(content)" />
- </div>
- </div>
- </template>
- <div v-if="content.data">
- <template v-if="typeof content.data === 'string'">{{ content.data }}</template>
- <el-tabs v-else v-model="content.tab">
- <el-tab-pane v-for="(v, k) in content.data.data[0]" :key="k" :label="k" :name="k" class="overflow-y-auto !h-360px">
- <template v-if="k === 'html'">
- <div class="position-sticky float-right">
- <el-button
- type="primary"
- class="cursor-pointer"
- @click="content.showHtml = !content.showHtml"
- :icon="SetUp"
- circle
- />
- </div>
- <pre v-if="!content.showHtml">{{ v }}</pre>
- <div v-else v-html="v"></div>
- </template>
- <pre v-else>{{ v || '暂无数据' }}</pre>
- </el-tab-pane>
- </el-tabs>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </ContentWrap>
- <el-drawer
- v-model="drawer"
- class="!w-50vw"
- :with-header="false"
- :modal="true"
- >
- <iframe class="!w-100% !h-[calc(100vh-90px)]" :src="drawerUrl" frameborder="0"></iframe>
- <el-divider class="!ma-0" />
- <div class="position-sticky left-20px !h-50px lh-50px">
- <el-button type="primary" class="!w-100px" @click="drawer = false; drawerUrl = ''">关 闭</el-button>
- </div>
- </el-drawer>
- </template>
- <script setup>
- /** 人才采集 网页解析 */
- import FirecrawlApp from '@mendable/firecrawl-js'
- import { SetUp } from '@element-plus/icons-vue'
- const message = useMessage() // 消息弹窗
- const { t } = useI18n() // 国际化
- const loading = ref(false)
- const queryParams = reactive({
- urls: 'https://mp.weixin.qq.com/s/WeCRR3zN3fPvlGR4t8YFDA'
- })
- const queryFormRef = ref()
- const contents = ref([])
- const drawer = ref(false)
- const drawerUrl = ref('')
- const showPage = (content) => {
- drawer.value = true
- drawerUrl.value = content.url
- }
- const handleReload = async (content) => {
- content.data = null
- const res = await handleData(queryParams.urls)
- content.tab = 0
- content.data = res
- }
- const handleData = async (url) => {
- try {
- const app = new FirecrawlApp({ apiKey: 'fc-85c1550c6db64ce4ae8f2d2cd2606e6f' })
- const crawlResponse = await app.crawlUrl(url, {
- limit: 100,
- scrapeOptions: {
- formats: ['markdown', 'html']
- }
- })
- if (!crawlResponse.success) {
- throw new Error(`Failed to crawl: ${crawlResponse.error}`)
- }
- return crawlResponse
- } catch (error) {
- return error.message
- }
- }
- // 执行
- const handleExecute = async () => {
- if (!queryParams.urls) return
- contents.value = []
- const urls = queryParams.urls.split(',').map(url => url.trim()).filter(url => url)
- if (urls.length === 0) return
- urls.forEach(url => {
- contents.value.push({ url, tab: 'markdown', showHtml: false, data: null })
- })
- const crawlPromises = urls.map(async (url, index) => {
- const res = await handleData(url)
- contents.value[index] = { ...contents.value[index], data: res }
- })
- try {
- await Promise.all(crawlPromises)
- console.log('All crawls completed:', contents.value); // 可在此处添加成功回调
- } catch (error) {
- console.error('爬取过程中发生错误:', error);
- }
- }
- </script>
|