您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动爬取微博帖子内容的脚本(仅用于学术研究目的,研究结束后将删除)
// ==UserScript== // @name 微博内容爬虫 // @namespace http://tampermonkey.net/ // @version 0.5 // @description 自动爬取微博帖子内容的脚本(仅用于学术研究目的,研究结束后将删除) // @author 稳稳 // @match https://weibo.com/* // @grant GM_xmlhttpRequest // @grant GM_download // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== (function() { 'use strict'; // 配置项 const config = { autoScroll: true, // 是否自动滚动页面 scrollInterval: 2000, // 滚动间隔(毫秒) maxPosts: 300, // 最大爬取帖子数 saveToFile: true, // 是否保存到文件 API_HOST: 'http://localhost:8888' // 本地MAMP服务器地址 }; // 存储爬取的数据 let collectedPosts = []; // 主函数 function init() { // 添加控制面板 addControlPanel(); // 开始监听页面变化 observePageChanges(); } // 添加控制面板 function addControlPanel() { const panel = document.createElement('div'); panel.style.cssText = ` position: fixed; top: 20px; right: 20px; background: white; padding: 10px; border: 1px solid #ccc; border-radius: 5px; z-index: 9999; `; panel.innerHTML = ` <button id="startCrawl">开始爬取</button> <button id="stopCrawl">停止爬取</button> <button id="exportData">导出数据</button> <div id="crawlStatus">状态: 未开始</div> `; document.body.appendChild(panel); // 添加事件监听 document.getElementById('startCrawl').addEventListener('click', startCrawling); document.getElementById('stopCrawl').addEventListener('click', stopCrawling); document.getElementById('exportData').addEventListener('click', exportData); } // 监听页面变化 function observePageChanges() { const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes && mutation.addedNodes.length > 0) { // 检查新增的节点是否包含微博内容 mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { extractPostContent(node); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); } // 提取帖子内容 function extractPostContent(node) { // 查找帖子内容区域 const posts = node.querySelectorAll('[class*="Feed_body"]'); posts.forEach(post => { const postData = { id: getPostId(post), content: getTextContent(post), author: getAuthor(post), time: getPostTime(post), interactions: getInteractions(post) }; if (postData.id && !isDuplicate(postData)) { collectedPosts.push(postData); updateStatus(); // 上传到服务器 uploadPost(postData); } }); } // 获取帖子ID function getPostId(post) { const feedCard = post.closest('[class*="Feed_card"]'); return feedCard ? feedCard.getAttribute('data-id') || '' : ''; } function getTextContent(post) { const contentNode = post.querySelector('[class*="detail_wbtext"]'); return contentNode ? contentNode.textContent.trim() : ''; } function getAuthor(post) { const authorNode = post.querySelector('[class*="ALink_name"]'); const verifiedNode = post.querySelector('[class*="woo_svg_"]'); return authorNode ? { name: authorNode.textContent.trim(), link: authorNode.href, verified: verifiedNode ? verifiedNode.id : null } : null; } function getPostTime(post) { const timeNode = post.querySelector('[class*="Feed_from"] a'); return timeNode ? timeNode.textContent.trim() : ''; } function getInteractionCount(post, type) { const node = post.querySelector(`[class*="toolbar_${type}"]`); if (!node) return 0; const countText = node.textContent.trim().replace(/[^0-9]/g, ''); return countText ? parseInt(countText) : 0; } // 获取互动数据 function getInteractions(post) { return { likes: getInteractionCount(post, '点赞'), comments: getInteractionCount(post, '评论'), reposts: getInteractionCount(post, '转发') }; } // 获取互动数量 function getInteractionCount(post, type) { const node = post.querySelector(`[title*="${type}"]`); return node ? parseInt(node.textContent) || 0 : 0; } // 检查是否重复 function isDuplicate(postData) { return collectedPosts.some(post => post.id === postData.id); } // 更新状态 function updateStatus() { const statusDiv = document.getElementById('crawlStatus'); if (statusDiv) { statusDiv.textContent = `状态: 已爬取 ${collectedPosts.length} 条帖子`; } } // 开始爬取 function startCrawling() { // 实现开始爬取的逻辑 document.getElementById('crawlStatus').textContent = '状态: 爬取中...'; } // 停止爬取 function stopCrawling() { // 实现停止爬取的逻辑 document.getElementById('crawlStatus').textContent = '状态: 已停止'; } // 导出数据 function exportData() { const blob = new Blob([JSON.stringify(collectedPosts, null, 2)], {type: 'application/json'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `weibo_posts_${new Date().toISOString()}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // 上传帖子数据到服务器 function uploadPost(postData) { GM_xmlhttpRequest({ method: 'POST', url: `${config.API_HOST}/weibo-server/save_weibo.php`, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' }, data: JSON.stringify(postData), onload: function(response) { try { const result = JSON.parse(response.responseText); if (result.success) { console.log('数据上传成功:', postData.id); } else { console.error('数据上传失败:', result.message); } } catch (e) { console.error('解析响应失败:', e); } }, onerror: function(error) { console.error('上传请求失败:', error); } }); } // 启动脚本 init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址