Python3.10 + Firecrawl 下载公众号文章

获取Firecrawl apikey

打开官网,使用github账号登录
https://www.firecrawl.dev/
在这里插入图片描述
进入个人中心
https://www.firecrawl.dev/app/api-keys
在这里插入图片描述

使用PyCharm创建python项目

在这里插入图片描述

创建.env

# API配置
FIRECRAWL_API_KEY=fc-9*********0816d5ac6b20
# 输出配置
OUTPUT_DIR=output

创建url_list.txt

https://mp.weixin.qq.com/s/NH4Odi-xT_hlmZdGe0dw6Q

创建wechat_crawler.py

import os
from typing import Dict, Any, List
from firecrawl import FirecrawlApp
from dotenv import load_dotenv
import logging
import re# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)# 加载.env文件
load_dotenv()class WeChatCrawler:def __init__(self, api_key: str = None):"""初始化微信公众号爬虫Args:api_key: Firecrawl API密钥"""self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY')if not self.api_key:raise ValueError("请提供Firecrawl API密钥")self.app = FirecrawlApp(api_key=self.api_key)self.output_dir = os.getenv('OUTPUT_DIR', 'output')# 创建输出目录if not os.path.exists(self.output_dir):os.makedirs(self.output_dir)def read_urls_from_file(self, file_path: str = 'url_list.txt') -> List[str]:"""从文件中读取URL列表Args:file_path: URL列表文件路径Returns:List[str]: URL列表"""urls = []try:with open(file_path, 'r', encoding='utf-8') as file:for line in file:url = line.strip()if url and url.startswith('http'):  # 确保是有效的URLurls.append(url)logger.info(f"从 {file_path} 读取到 {len(urls)} 个URL")except FileNotFoundError:logger.error(f"文件 {file_path} 不存在")except Exception as e:logger.error(f"读取文件时出错: {e}")return urlsdef scrape_url(self, url: str) -> Dict[str, Any]:"""爬取单个URL的文章内容Args:url: 要爬取的URLReturns:Dict: 爬取结果"""try:logger.info(f"开始爬取: {url}")# 使用Firecrawl爬取URLresult = self.app.scrape_url(url, formats=['markdown', 'html'])logger.info(f"成功爬取: {url}")return resultexcept Exception as e:logger.error(f"爬取 {url} 时出错: {e}")return {'error': str(e)}def save_markdown(self, content: str, filename: str) -> None:"""保存Markdown内容到文件Args:content: Markdown内容filename: 文件名"""try:file_path = os.path.join(self.output_dir, filename)with open(file_path, 'w', encoding='utf-8') as file:file.write(content)logger.info(f"成功保存: {file_path}")except Exception as e:logger.error(f"保存文件 {filename} 时出错: {e}")def generate_filename(self, url: str) -> str:"""根据URL生成文件名Args:url: URLReturns:str: 生成的文件名"""try:# 尝试从微信URL中提取标识符# 微信公众号文章URL格式: https://mp.weixin.qq.com/s/标识符match = re.search(r'/s/([A-Za-z0-9_-]+)', url)if match:identifier = match.group(1)return f"wechat_article_{identifier}.md"else:# 如果解析失败,使用时间戳import timetimestamp = int(time.time())return f"wechat_article_{timestamp}.md"except:# 如果解析失败,使用时间戳import timetimestamp = int(time.time())return f"wechat_article_{timestamp}.md"def crawl_all_urls(self) -> None:"""爬取所有URL并保存为Markdown文件"""urls = self.read_urls_from_file()if not urls:logger.warning("没有找到要爬取的URL")returnlogger.info(f"开始爬取 {len(urls)} 个URL")for i, url in enumerate(urls, 1):logger.info(f"正在处理第 {i}/{len(urls)} 个URL")result = self.scrape_url(url)# 检查返回结果中是否包含markdown内容# 处理可能的超时或其他错误try:# 检查是否有错误if hasattr(result, 'error') and result.error:logger.error(f"爬取 {url} 出错: {result.error}")continue# 检查是否有markdown内容if hasattr(result, 'markdown') and result.markdown:filename = self.generate_filename(url)self.save_markdown(result.markdown, filename)else:# 尝试转换为字典result_dict = result.dict() if hasattr(result, 'dict') else resultif isinstance(result_dict, dict) and 'markdown' in result_dict and result_dict['markdown']:filename = self.generate_filename(url)self.save_markdown(result_dict['markdown'], filename)else:logger.error(f"无法获取 {url} 的Markdown内容")except Exception as e:logger.error(f"处理 {url} 的结果时出错: {e}")if __name__ == "__main__":try:# 创建爬虫实例crawler = WeChatCrawler()# 爬取所有URLcrawler.crawl_all_urls()print("所有文章爬取完成!")except Exception as e:logger.error(f"程序执行出错: {e}")print(f"程序执行出错: {e}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93101.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IoT/透过oc_lwm2m/boudica150 源码中的AT指令序列,分析NB-IoT接入华为云物联网平台IoTDA的工作机制

文章目录概述指令调用顺序具体接入指令分析ATE0 关闭回显ATQREGSWT 设置(平台)注册模式ATQLWSREGIND0 手动注册平台set_autoconnect / ATNCONFIGATNBANDx,xset_plmn / ATCOPS_set_apn / ATCGDCONT(安全)接入参数 CDPDTLSPSKATNNMI 设置新消息指示_check_…

Android UI(一)登录注册 - Compose

UI - 登录注册 - Compose一、声明式UI1. **颠覆传统开发模式**2. **技术优势**3. **开发效率提升**4. **未来生态方向**5. **实际影响**二、创建项目1. Compose UI结构2. Scaffold3. 可组合函数三、创建组件页面1. LoginPage2. RegisterPage3. MainPage四、导航1. 添加依赖2. 使…

分享10个ai生成ppt网站(附ai生成ppt入口)

实测对比:15页PPT从3小时压缩到3分钟的秘密武器 当ChatGPT能写方案、Midjourney能画图,做PPT还在手动排版就OUT了!这些AI生成PPT网站已实现「输入文案秒出设计稿」,无论职场汇报、毕业答辩还是路演融资,零设计基础也能…

最强开源视频模型通义万相wan2.1在comfyui中的安装应用详解

摘要:阿里巴巴开源通义万相Wan2.1模型,支持文生视频、图生视频等多种功能,并整合关键环节简化创作流程。官方和Kiji版本需配套使用各自工作流。低显存显卡可使用GGUF模型解决方案,最低适配4G显存。ComfyUI已原生支持该模型&#x…

机器学习:基于OpenCV和Python的智能图像处理 实战

机器学习:基于OpenCV和Python的智能图像处理实战——待填坑图像处理基础图像的基本表示方法图像处理的基本操作图像运算图像的色彩空间转换图像几何变换4.1 仿射变换4.2 重映射4.3 投影变换 4.4 极坐标变换5 图像直方图处理7 图像阈值处理8 图像形态学处理github地址…

proteus实现简易DS18B20温度计(stm32)

一、新建proteus工程 具体看前面文章 二、搭建电路 需要配置供电网络以及寻找元器件,细节看前面文章,下面给出电路图 电路包含了五个部分: 1、DS18B20:数据引脚记得上拉 2、stm32电路 3、串口电路(右下角那个器件…

Autoppt-AI驱动的演示文稿生成工具

本文转载自:Autoppt-AI驱动的演示文稿生成工具 - Hello123工具导航 ** 一、 Autoppt:AI 驱动的智能演示文稿生成工具 Autoppt 是一款基于人工智能的在线演示文稿生成平台,通过输入主题或上传文档(Word/PDF/ 图片等)&…

Flink on YARN启动全流程深度解析

Flink on YARN 模式启动流程及核心组件协作详解整个过程分为三个主要阶段:​​JobManager 启动​​(作业提交与 AM 初始化)​​TaskManager 资源分配与启动​​​​任务部署与执行​​第一阶段:作业提交与 JobManager (AM) 启动​…

安卓开发者自学鸿蒙开发1基础入门

1.基础 声明式UI:​​ ​​核心:​​ 你​​声明​​你想要UI是什么样子(在build()方法里描述),而不是一步步命令式地创建和操作View对象(findViewById, setText, setOnClickListener)。 模块化…

弹性扩展新范式:分布式LLM计算的FastMCP解决方案

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。如果你想系统学习AI大模型应用开发,挑战AI高薪岗位,可在文章底部联系。在现代大语言模型(LLM)应用架构中…

springboot项目不同平台项目通过http接口AES加密传输

前言: 在公司协作开发的过程中,自己的项目是公共调用平台,也可以说是中转平台,供公司其他团队的项目进行接口调用。因为是不同团队项目之间的相互调用,所以不能通过openFeign远程调用。只能通过http远程调用&#xff…

推荐5个网页模板资源网

1. 企业模板官方网站: http://www.qimoban.com介绍:企业模板(qimoban.com )是一个专注于提供丰富多样的企业模板的优质平台,致力于为企业和个人打造高效、专业、个性化的模板获取渠道。该平台提供海量的企业模板资源,涵盖企业官网…

Redis持久化机制(RDB AOF)

1. RDB RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程分为手动触发和 自动触发,存储的是二进制数据。 1.1 手动触发 使用 save 和 bgsave 命令触发: save:Redis服务主进程阻塞式执行持久化操作&…

【css】让浏览器支持小于12px的文字

【css】让浏览器支持小于12px的文字.demo {display: inline-block;/** 使用Webkit引擎的变换属性(主要针对旧版Safari/Chrome) **/-webkit-transform: scale(0.8); }注意:display: inline-block; 一定要加上!1.transform: scale(…

机器学习-基础入门:从概念到核心方法论

在人工智能飞速发展的今天,机器学习作为其核心技术,正深刻改变着我们的生活与工作。从 AlphaGo 战胜围棋世界冠军,到日常的智能推荐、人脸识别,机器学习的应用无处不在。本文将从基础概念出发,带你系统了解机器学习的核…

《Leetcode》-面试题-hot100-动态规划

题目列表 70. 爬楼梯 简单难度 leetcode链接 118. 杨辉三角 简单难度 leetcode链接 198. 打家劫舍 中等难度 leetcode链接 279.完全平方数 中等难度 leetcode链接 322.零钱兑换 中等难度 leetcode链接 139.单词拆分 中等难度 leetcode链接 300.最长递增子序列 中等难度 l…

数巅中标中建科技AI知识库项目,开启建筑业数智化新篇章

AI正以前所未有的迅猛态势渗透进建筑业的每一处脉络。在这场数智化转型浪潮中,AI技术如何与建筑业基因深度融合?如何充分释放数据价值?近日,数巅成功中标中建科技集团有限公司“企业AI知识库研发”项目,这一“大语言模…

想要PDF翻译保留格式?用对工具是关键

嘿,朋友!最近有没有被PDF翻译的事儿搞得焦头烂额呀?尤其是碰到韩文PDF文件的时候,是不是更头疼了?别担心,我最近也遇到了类似的问题,试了不少软件,发现有五款软件在处理韩文PDF翻译时…

【MySQL✨】服务器安装 MySQL 及配置相关操作

1. 安装 MySQL 在安装 MySQL 时,如果使用官方 RPM 源,会遇到 GPG 密钥验证失败的错误,可以按照以下步骤解决: 解决 GPG 密钥验证失败的问题下载 MySQL 官方 GPG 密钥 使用以下命令下载并安装 MySQL 的官方 GPG 密钥: w…

大数据量返回方案(非分页)

一、普通方式返回100万条数据RestController RequestMapping("/bad") public class BadController {Autowiredprivate UserRepository userRepository;/*** 危险&#xff01;一次性加载 100 万条到内存*/GetMapping("/all-users")public List<User> …