Python自制爬虫框架如何整合多家IT博客平台的文章?
这样就能更方便地寻找技术干货了
Demo 地址: https://techattic.herokuapp.com
自制的爬虫框架介绍: https://zhuanlan.zhihu.com/p/34917713
整理好的 Python 总结: https://github.com/alphardex/python-recipe
Python自制爬虫框架如何整合多家IT博客平台的文章?
3 回复
要整合多家IT博客平台的文章,你需要设计一个可扩展的爬虫框架。核心思路是抽象出通用的爬取流程,然后为每个平台实现具体的解析器。
下面是一个基础框架示例:
import requests
from abc import ABC, abstractmethod
from typing import List, Dict
import json
class Article:
"""文章数据模型"""
def __init__(self, title: str, content: str, author: str, url: str):
self.title = title
self.content = content
self.author = author
self.url = url
def to_dict(self):
return {
'title': self.title,
'content': self.content,
'author': self.author,
'url': self.url
}
class BaseCrawler(ABC):
"""爬虫基类"""
def __init__(self, base_url: str):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
@abstractmethod
def parse_article_list(self, html: str) -> List[str]:
"""解析文章列表页,返回文章详情页链接"""
pass
@abstractmethod
def parse_article_detail(self, html: str) -> Article:
"""解析文章详情页,返回Article对象"""
pass
def fetch(self, url: str) -> str:
"""发送HTTP请求"""
response = self.session.get(url, timeout=10)
response.raise_for_status()
return response.text
def crawl(self, start_url: str) -> List[Article]:
"""执行爬取流程"""
articles = []
# 获取列表页
list_html = self.fetch(start_url)
article_urls = self.parse_article_list(list_html)
# 遍历每篇文章
for url in article_urls:
try:
detail_html = self.fetch(url)
article = self.parse_article_detail(detail_html)
articles.append(article)
except Exception as e:
print(f"爬取 {url} 失败: {e}")
return articles
# 具体平台实现示例
class CSDNCrawler(BaseCrawler):
"""CSDN爬虫"""
def parse_article_list(self, html: str) -> List[str]:
# 这里简化处理,实际需要解析HTML
# 可以使用BeautifulSoup或lxml
import re
return re.findall(r'https://blog.csdn.net/\w+/article/details/\d+', html)
def parse_article_detail(self, html: str) -> Article:
# 解析CSDN文章页面的具体逻辑
# 这里返回示例数据
return Article(
title="示例标题",
content="示例内容",
author="示例作者",
url="https://example.com"
)
class JuejinCrawler(BaseCrawler):
"""掘金爬虫"""
def parse_article_list(self, html: str) -> List[str]:
# 解析掘金文章列表
import re
return re.findall(r'https://juejin.cn/post/\d+', html)
def parse_article_detail(self, html: str) -> Article:
# 解析掘金文章详情
return Article(
title="掘金文章",
content="掘金内容",
author="掘金作者",
url="https://juejin.cn"
)
class CrawlerManager:
"""爬虫管理器"""
def __init__(self):
self.crawlers = {}
def register_crawler(self, name: str, crawler: BaseCrawler):
self.crawlers[name] = crawler
def run_all(self, config: Dict[str, str]) -> Dict[str, List[Article]]:
"""运行所有爬虫"""
results = {}
for name, start_url in config.items():
if name in self.crawlers:
print(f"开始爬取 {name}...")
articles = self.crawlers[name].crawl(start_url)
results[name] = articles
print(f"{name} 爬取完成,获取 {len(articles)} 篇文章")
return results
def save_results(self, results: Dict[str, List[Article]], filename: str):
"""保存结果到JSON文件"""
data = {}
for platform, articles in results.items():
data[platform] = [article.to_dict() for article in articles]
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 使用示例
if __name__ == "__main__":
manager = CrawlerManager()
# 注册爬虫
manager.register_crawler("csdn", CSDNCrawler("https://blog.csdn.net"))
manager.register_crawler("juejin", JuejinCrawler("https://juejin.cn"))
# 配置各平台的起始URL
config = {
"csdn": "https://blog.csdn.net/nav/python",
"juejin": "https://juejin.cn/frontend"
}
# 执行爬取
results = manager.run_all(config)
# 保存结果
manager.save_results(results, "articles.json")
这个框架的关键点:
-
抽象基类:
BaseCrawler定义了爬虫的标准接口,所有平台爬虫都要继承并实现parse_article_list和parse_article_detail方法。 -
数据模型:
Article类统一了文章的数据结构,确保不同平台的数据格式一致。 -
管理器模式:
CrawlerManager负责注册和调度各个爬虫,方便扩展新平台。 -
扩展性:要新增平台,只需创建一个新的爬虫类继承
BaseCrawler,然后在管理器中注册即可。
实际使用时需要注意:
- 需要根据各平台的实际HTML结构实现具体的解析逻辑
- 建议使用
BeautifulSoup或lxml进行HTML解析 - 添加适当的延迟和错误处理避免被封IP
- 遵守各平台的robots.txt协议
总结建议:用抽象基类定义接口,为每个平台实现具体解析器。
hello, 欢迎使用 crawlab 来集成 looter,https://www.github.com/tikazyq/crawlab
没人做网站爬虫规则共享平台吗?爬虫框架太多

