写爬虫这事吧,简单的时候简单到一行代码,复杂起来却能让人头秃。要想高效地处理爬虫需求,一个自己的爬虫框架简直就是神器。接下来,我带你走一遍思路,手把手写出一个可以复用的Python爬虫框架。
框架的核心结构
一个爬虫框架主要包含以下几个部分:请求管理器、数据解析器、任务队列、存储模块和异常处理模块。这几个模块各司其职,组合起来就能让框架变得既清晰又灵活。
先来一个目录结构的简单示意:
my_spider/
├── main.py # 入口文件
├── request_manager.py # 请求管理模块
├── parser.py # 数据解析模块
├── storage.py # 数据存储模块
└── utils.py # 工具模块
请求管理器:处理HTTP请求
爬虫的第一步,当然是发请求啦。这里可以用Python的明星库requests
来搞定。为了支持高并发,可以加上一个简单的线程池。
# request_manager.py
import requests
from concurrent.futures import ThreadPoolExecutor
class RequestManager:
def __init__(self, max_workers=5):
self.executor = ThreadPoolExecutor(max_workers=max_workers)
def fetch(self, url, method="GET", headers=None, data=None):
try:
response = requests.request(method, url, headers=headers, data=data)
response.raise_for_status()
return response.text
except requests.RequestException as e:
print(f"请求失败:{url}, 错误:{e}")
return None
def async_fetch(self, urls):
results = []
for url in urls:
results.append(self.executor.submit(self.fetch, url))
return [task.result() for task in results]
实际应用场景
- 单个请求:
fetch(url)
- 多个请求并发:
async_fetch(url_list)
温馨提示:并发请求时,不要一次性扔太多URL,容易被目标网站封杀,适当加点time.sleep
。
数据解析器:从页面提取有用信息
拿到HTML还不够,接下来得从中提取有用的数据。可以用BeautifulSoup
或者lxml
。
# parser.py
from bs4 import BeautifulSoup
class Parser:
def parse_html(self, html, selector):
try:
soup = BeautifulSoup(html, 'html.parser')
return [element.text for element in soup.select(selector)]
except Exception as e:
print(f"解析失败:{e}")
return []
# 示例用法
# html = "<html><body><h1>Hello</h1></body></html>"
# parser = Parser()
# print(parser.parse_html(html, "h1"))
学习技巧
CSS选择器的基础得过关! 比如div.class_name
选中某个类名的元素,#id_name
选中ID,ul > li
表示父子关系,这些小技巧能极大提高解析效率。
任务队列:让任务一个接一个地跑
任务队列是爬虫的大脑,负责调度任务,确保每一步有条不紊。
# main.py
import queue
from request_manager import RequestManager
from parser import Parser
class Spider:
def __init__(self):
self.task_queue = queue.Queue()
self.request_manager = RequestManager()
self.parser = Parser()
def add_task(self, url):
self.task_queue.put(url)
def run(self):
while not self.task_queue.empty():
url = self.task_queue.get()
html = self.request_manager.fetch(url)
if html:
data = self.parser.parse_html(html, "h1") # 假设我们只抓h1标签
print(f"URL: {url}, Data: {data}")
# 示例用法
spider = Spider()
spider.add_task("https://example.com")
spider.run()
温馨提示:
任务队列的设计要结合实际需求,比如深度爬取时需要用到多级队列。
数据存储模块:保存抓取到的数据
爬虫的最终目标是存数据!咱们用sqlite3
搞一个简单的数据库存储。
# storage.py
import sqlite3
class Storage:
def __init__(self, db_name="data.db"):
self.conn = sqlite3.connect(db_name)
self.cursor = self.conn.cursor()
self.cursor.execute(
"CREATE TABLE IF NOT EXISTS data (id INTEGER PRIMARY KEY, content TEXT)"
)
def save(self, content):
self.cursor.execute("INSERT INTO data (content) VALUES (?)", (content,))
self.conn.commit()
def close(self):
self.conn.close()
# 示例用法
# storage = Storage()
# storage.save("Hello, World!")
# storage.close()
学习技巧:
数据量大时,用pandas
写入CSV文件或者直接用分布式数据库,效率会更高。
异常处理:让爬虫更健壮
爬虫天生脆弱,目标网站可能封IP、变更HTML结构,甚至直接挂掉。这个时候,异常处理模块就派上用场了。
# utils.py
import time
def retry(func, retries=3, delay=2):
for _ in range(retries):
result = func()
if result:
return result
time.sleep(delay)
return None
小细节:在关键的地方,比如HTTP请求或者数据解析,都加上try-except
块,防止爬虫直接崩掉。
写个总结:怎么高效跑起来
框架搭好后,只要往里面塞URL,调整一下解析逻辑和存储逻辑,爬虫就能高效跑起来了。
整套逻辑就是:任务队列 -> 请求管理器 -> 数据解析器 -> 数据存储模块 -> 异常处理兜底。每个模块都独立又灵活,可以按需改进。
写爬虫别贪心,记住“小步快跑,测试为王”,能稳定抓取10个页面就算成功,剩下的可以慢慢优化!
彩蛋时间
走过路过不要错过,为大家准备了一份pycharm破解工具,感兴趣的朋友可以看看哈:最新pycharm破解
评论区