Scrapy利器:构建强大爬虫,轻松获取所需数据!
爬虫开发中,Scrapy绝对是一把利器。它不单单是一个爬虫框架,更像是一个完整的数据采集平台。写过爬虫的同学大概率用过requests+beautifulsoup的组合,但遇到大规模爬取时就会感觉力不从心。这时候就要请出Scrapy这个重量级选手了。
框架核心解析
Scrapy采用组件化设计,各个模块之间配合默契。主要包含这么几个核心组件:
# Spider组件示例
import scrapy
class BookSpider(scrapy.Spider):
name = 'bookspider'
start_urls = ['http://books.example.com']
def parse(self, response):
for book in response.css('.book-item'):
yield {
'title': book.css('.title::text').get(),
'price': book.css('.price::text').get(),
'author': book.css('.author::text').get()
}
⚠️ 小贴士:
- Spider类必须定义name属性
- parse方法是处理响应的入口
- 用yield返回数据比return更省内存
中间件玩法
中间件可以说是Scrapy的一大亮点,能让你在请求前后做各种骚操作:
class CustomMiddleware:
def process_request(self, request, spider):
# 随机切换User-Agent
request.headers['User-Agent'] = get_random_ua()
def process_response(self, request, response, spider):
# 检查响应状态
if response.status != 200:
logging.warning(f'Bad status: {response.status}')
return response
项目实战:豆瓣图书爬虫
光说不练假把式,整个实例体会下:
class DoubanSpider(scrapy.Spider):
name = 'douban'
custom_settings = {
'ROBOTSTXT_OBEY': False, # 看心情遵守robots协议
'CONCURRENT_REQUESTS': 16 # 并发数调高点
}
def start_requests(self):
# 构造初始请求
base_url = 'https://book.douban.com/tag/编程?start={}&type=T'
for i in range(0, 200, 20):
yield scrapy.Request(base_url.format(i))
def parse(self, response):
books = response.css('#subject_list .subject-item')
for book in books:
yield {
'title': book.css('h2 a::text').get().strip(),
'rate': book.css('.rating_nums::text').get(),
'desc': book.css('.pub::text').get().strip()
}
⚠️ 小贴士:
- 记得处理反爬,该上代理上代理
- 数据清洗很重要,strip()走起来
- 别把并发调太高,小心被封
调度器优化
默认的调度器用的内存队列,数据量大了会有点吃不消。可以换用Redis来存储请求队列:
# settings.py
SCHEDULER = “scrapy_redis.scheduler.Scheduler”
DUPEFILTER_CLASS = “scrapy_redis.dupefilter.RFPDupeFilter”
REDIS_URL = 'redis://localhost:6379'
⚠️ 小贴士:
- Redis持久化记得打开
- 定期清理过期请求
- 善用布隆过滤器去重
Pipeline数据处理
爬下来的数据总得存起来,Pipeline就是干这个的:
class MongoPipeline:
def __init__(self):
self.mongo_uri = 'mongodb://localhost:27017'
self.mongo_db = 'books'
def process_item(self, item, spider):
# 存入MongoDB
collection = self.mongo_db['douban_books']
collection.insert_one(dict(item))
return item
写爬虫最重要的是要有耐心,慢慢摸索目标网站的特点。代码写得再漂亮,爬不到数据也是白搭。
⚠️ 小贴士:
- 善用延时和随机等待
- 数据备份很重要
- 监控爬虫运行状态
数据采集这活儿吧,讲究的是持久战。代码写完只是开始,调试优化才是重点。不过有了Scrapy这神器,爬虫开发效率蹭蹭往上涨,剩下的就是跟反爬斗智斗勇了。
来源:青言悉语
THE END