Scrapy 是 Python 生态中主流的高性能网页抓取框架,内置异步 I/O 和并发请求处理,适合大规模数据采集。本文从头搭建一个完整项目,覆盖安装配置、项目结构、爬虫编写、分页逻辑、数据导出、动态内容处理以及通过 Pipeline 将抓取结果存入 MongoDB。
- pip install scrapy
- scrapy version
复制代码 安装完成后执行 scrapy version 验证版本号。
创建项目并理解目录结构:- scrapy startproject myproject
- cd myproject
复制代码 生成的结构中,scrapy.cfg 是项目配置文件,myproject/ 下包含 items.py(定义数据字段)、middlewares.py(中间件)、pipelines.py(数据存储逻辑)、settings.py(项目设置)、spiders/(存放爬虫脚本)。
编写第一个 Spider:在 myproject/spiders/ 下创建 quotes_spider.py。该爬虫抓取 quotes.toscrape.com 上的名言、作者和标签,并支持分页跟进。- import scrapy
- class QuotesSpider(scrapy.Spider):
- name = "quotes"
- start_urls = ['http://quotes.toscrape.com']
- def parse(self, response):
- for quote in response.css('div.quote'):
- yield {
- 'text': quote.css('span.text::text').get(),
- 'author': quote.css('span small::text').get(),
- 'tags': quote.css('div.tags a.tag::text').getall(),
- }
- next_page = response.css('li.next a::attr(href)').get()
- if next_page:
- yield response.follow(next_page, self.parse)
复制代码 运行爬虫并导出数据:- scrapy crawl quotes -o quotes.json
复制代码 JSON、CSV、XML 均可通过 -o 参数指定。
优化设置:在 settings.py 中修改 USER_AGENT 避免被屏蔽,调整 CONCURRENT_REQUESTS 控制并发数,设置 DOWNLOAD_DELAY 降低服务器压力。- USER_AGENT = 'myproject (+http://www.yourdomain.com)'
- CONCURRENT_REQUESTS = 16
- DOWNLOAD_DELAY = 1
复制代码
处理动态内容:Scrapy 本身无法执行 JavaScript,需集成 Scrapy-Splash。安装 pip install scrapy-splash 后,在 settings.py 添加中间件和去重过滤器。- DOWNLOADER_MIDDLEWARES = {
- 'scrapy_splash.SplashCookiesMiddleware': 723,
- 'scrapy_splash.SplashMiddleware': 725,
- 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
- }
- SPIDER_MIDDLEWARES = {
- 'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
- }
- DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
- HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
复制代码
数据持久化:通过 Pipeline 将抓取结果存入 MongoDB。安装 pymongo:编辑 pipelines.py:- import pymongo
- class MongoPipeline:
- def open_spider(self, spider):
- self.client = pymongo.MongoClient("mongodb://localhost:27017/")
- self.db = self.client["scrapy_db"]
- def close_spider(self, spider):
- self.client.close()
- def process_item(self, item, spider):
- self.db["quotes"].insert_one(dict(item))
- return item
复制代码 在 settings.py 中激活 Pipeline:- ITEM_PIPELINES = {
- 'myproject.pipelines.MongoPipeline': 300,
- }
复制代码 至此,一个完整的 Scrapy 抓取项目已搭建完成,从静态页面到动态渲染,再到数据库存储,满足了常见的生产级数据采集需求。 |