Scrapy部署管理教程:新手入門指南
Scrapy部署管理教程涵盖了如何将Scrapy爬虫与Django和Flask集成,以及如何使用Celery和APScheduler等工具设置定时任务。教程还包括了Scrapy爬虫的日志记录和监控方法,帮助开发者更好地管理和维护爬虫。文章还提供了常见问题及其解决方案,确保爬虫能够稳定运行。
Scrapy简介与安装Scrapy是什么
Scrapy是Python语言编写的一款快速、轻量级的Web爬虫框架。它提供了强大的数据处理能力以及灵活的扩展性,使得开发者可以方便地从网站上抓取信息。Scrapy的设计宗旨是用于获取网页数据,但也可以用于其他用途,例如API接口抓取。Scrapy本身不含任何用于抓取或者缓存文件的代码,但提供了多种扩展插件,可以根据需要进行定制。
Scrapy的特性包括但不限于:
- 基于Twisted异步网络框架构建,可以高效地处理大量并发请求。
- 支持多种输出格式,如JSON、XML等。
- 强大的数据提取和处理能力,包括CSS选择器、XPath表达式等。
- 自动处理重定向、Cookies和登录等常见网站行为。
- 支持多种下载器中间件和爬虫中间件,方便扩展功能。
- 强大的异常处理机制,能够自动处理各种网络错误。
Scrapy框架适合于网站信息采集、数据挖掘、网络监控等场景,广泛应用于各种商业和科研项目中。对于需要频繁抓取互联网数据的开发者来说,Scrapy是一个不可或缺的工具。
Scrapy的安装方法
安装Scrapy通常需要Python环境已经搭建好。可以在Python官方网站(https://www.python.org/)下载安装最新版本的Python。安装完成后,可以利用pip工具来安装Scrapy。在命令行中执行以下命令:
pip install scrapy
安装过程中可能需要管理员权限,可以在命令前加上sudo
(对于Linux和Mac用户)或者使用管理员权限打开命令行窗口(对于Windows用户)。安装完成后,可以通过以下命令验证安装是否成功:
scrapy version
如果安装成功,该命令会输出Scrapy的版本信息。
Scrapy项目结构Scrapy项目的目录结构
Scrapy项目通常包含一系列文件和目录,每个文件和目录都有特定的作用。以下是常见的Scrapy项目结构及其内容:
myproject/
:项目的根目录,包含其他文件和子目录。myproject/spiders/
:存放爬虫文件的目录。每个爬虫文件都是一个Python文件,通常以.py
为扩展名。myproject/items.py
:定义要爬取的结构化数据的类,通常定义为Item
类。myproject/settings.py
:包含项目配置信息,如下载器设置、日志级别、中间件和管道等。myproject/pipelines.py
:定义数据处理流程,数据经过解析后会传递给管道,用于清洗、存储等操作。myproject/middlewares.py
:定义爬虫中间件,可以修改或扩展Scrapy请求和响应的行为。myproject/utils.py
:存放自定义的工具函数或类。myproject/requirements.txt
:列出项目依赖的Python库,便于其他开发者安装项目依赖。myproject/README.md
:项目说明文件,通常包含项目描述、安装说明、运行指南等信息。myproject/requirements.txt
:列出项目依赖的Python库,便于其他开发者安装项目依赖。myproject/.gitignore
:列出不需要版本控制的文件或目录。myproject/scraper.py
:自定义的爬虫脚本,可以定义在spiders/
目录下或者单独存放。
主要文件说明
settings.py
:包含项目的配置信息。可以设置下载延迟、重试次数、用户代理等。例如:
# settings.py
DOWNLOAD_DELAY = 1 # 每次请求之间间隔1秒
RETRY_TIMES = 5 # 重试次数
USER_AGENT = 'scrapy/2.4.1 (+http://docs.scrapy.org)' # 设置User-Agent
items.py
:定义爬取的数据结构。每个爬虫定义的数据结构通常包含一些字段。例如:
# items.py
import scrapy
class MyItem(scrapy.Item):
name = scrapy.Field()
url = scrapy.Field()
price = scrapy.Field()
pipelines.py
:定义处理爬取数据的流程。数据经过爬虫解析后会传递给管道进行处理,例如清洗、过滤、存储等操作。例如:
# pipelines.py
class MyPipeline:
def process_item(self, item, spider):
# 清洗数据
item['name'] = item['name'].strip()
item['price'] = float(item['price'])
return item
spiders/
:存放爬虫文件。每个爬虫文件都是一个Python类,通常以.py
为扩展名。爬虫类继承自scrapy.Spider
。例如:
# myproject/spiders/example_spider.py
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
start_urls = ['https://example.com']
def parse(self, response):
# 解析页面,提取数据
for item in response.css('div.item'):
yield {
'name': item.css('a::text').get(),
'url': item.css('a::attr(href)').get(),
'price': item.css('span.price::text').get(),
}
这些文件和目录共同构成了一个完整的Scrapy项目结构。通过定义爬虫、设置配置、编写管道,开发者可以高效地抓取和处理数据。
Scrapy爬虫编写基础创建简单的Scrapy爬虫
为了更好地理解Scrapy的工作流程,下面以一个简单的爬虫示例开始。这个示例将抓取一个网站的HTML页面,并提取页面中的某些数据。
爬虫的创建步骤
- 创建新的Scrapy项目
- 编写爬虫代码
- 运行爬虫
- 输出抓取结果
首先,在命令行中创建一个新的Scrapy项目:
scrapy startproject tutorial
这会创建一个名为tutorial
的目录,里面包含一个简单的Scrapy项目结构,如上一节所述。
接下来,在spiders
目录下创建一个新的爬虫文件example_spider.py
,并编写爬虫代码。以下是抓取"quotes.toscrape.com"网站的示例代码:
# tutorial/spiders/example_spider.py
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
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(),
}
该爬虫会访问http://quotes.toscrape.com/
网站,并使用CSS选择器解析页面结构,提取出每条引用的文本、作者和标签。
运行爬虫
在命令行中,进入项目根目录后,运行以下命令以启动爬虫:
scrapy crawl example
这将启动名为example
的爬虫,从start_urls
中定义的URL开始抓取数据。Scrapy会自动解析响应,执行parse
方法,并根据CSS选择器提取数据。在控制台输出中,可以看到抓取的数据。
输出抓取结果
默认情况下,Scrapy将输出抓取的数据到控制台。抓取的数据将显示在命令行输出中。如下所示:
2020-09-01 12:34:56 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/>
{'text': '“The world as we have created it is a projection of our
minds... Thoughts are the prima materia for the physics that
alchemizes the dream world of men into the bleak fact of the
real.”', 'author': 'Terry Pratchett', 'tags': ['inspirational']}
2020-09-01 12:34:56 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/>
{'text': '“The greatest glory of
flame is not the heat it generates, but the light it produces.”', 'author': 'John Wooden', 'tags': ['inspirational']}
爬虫运行时输出的内容包括每个抓取对象的时间戳、响应码、抓取的URL以及抓取的数据内容。
常用的Scrapy指令与设置
常用Scrapy指令
Scrapy提供了多个命令行指令,用于启动、停止或管理爬虫。以下是常用的Scrapy命令:
scrapy crawl <spider_name>
:启动指定的爬虫。scrapy startproject <project_name>
:创建一个新的Scrapy项目。scrapy genspider <spider_name> <domain>
:生成一个新的爬虫文件。scrapy list
:列出项目中的所有爬虫名称。scrapy view <url>
:在默认浏览器中打开指定的URL。scrapy shell <url>
:启动Scrapy shell,进入交互式命令行。scrapy check <spider_name>
:检查指定爬虫的合法性。
Scrapy的配置设置
Scrapy的各种设置可以在settings.py
文件中定义,这些设置会覆盖默认的Scrapy配置。以下是一些常用的设置:
USER_AGENT
:定义爬取时使用的User-Agent。例如:
USER_AGENT = 'MyScrapySpider'
DOWNLOAD_DELAY
:定义每个请求之间的延迟时间(以秒为单位)。例如:
DOWNLOAD_DELAY = 2.0 # 每个请求之间间隔2秒
CONCURRENT_REQUESTS_PER_DOMAIN
:定义对每个域名的最大并发请求数量。例如:
CONCURRENT_REQUESTS_PER_DOMAIN = 16
LOG_LEVEL
:设置日志级别。例如:
LOG_LEVEL = 'WARNING'
设置完成后,这些配置将影响到Scrapy的运行行为。开发者可以根据具体需求调整这些设置,以优化爬虫的性能和稳定性。
Scrapy爬虫进阶使用Item和Item Pipeline处理数据
在Scrapy中,Item
用于定义爬取的数据结构,而Pipeline
则用于数据清洗和存储等操作。以下是如何在项目中使用Item
和Pipeline
的示例。
定义Item
Item
是用于定义爬取的数据结构。通常定义在items.py
文件中。例如:
# tutorial/items.py
import scrapy
class QuoteItem(scrapy.Item):
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()
上述代码定义了一个QuoteItem
类,包含text
, author
和tags
三个字段。
使用Item
在爬虫中,使用yield
关键字返回一个Item
实例。例如:
# tutorial/spiders/example_spider.py
import scrapy
from tutorial.items import QuoteItem
class ExampleSpider(scrapy.Spider):
name = 'example'
start_urls = ['http://quotes.toscrape.com/']
def parse(self, response):
for quote in response.css('div.quote'):
item = QuoteItem()
item['text'] = quote.css('span.text::text').get()
item['author'] = quote.css('span small::text').get()
item['tags'] = quote.css('div.tags a.tag::text').getall()
yield item
定义Pipeline
Pipeline
是处理Item
的管道,可以进行数据清洗、过滤、存储等操作。通常定义在pipelines.py
文件中。例如:
# tutorial/pipelines.py
class QuotesPipeline:
def process_item(self, item, spider):
# 清洗数据
item['author'] = item['author'].strip()
item['text'] = item['text'].strip()
return item
上述代码定义了一个QuotesPipeline
类,用于清洗数据。
使用Pipeline
在settings.py
中设置启用的管道。例如:
# tutorial/settings.py
ITEM_PIPELINES = {
'tutorial.pipelines.QuotesPipeline': 300,
}
设置完成后,爬虫抓取的数据会传递给QuotesPipeline
进行处理。
处理登录验证和Cookies
在某些网站中,需要进行登录验证才能访问某些页面或内容。Scrapy提供了处理登录验证和Cookies的方法。
处理登录验证
登录验证通常需要发送登录表单数据。Scrapy可以通过自定义爬虫的start_requests
方法发送登录请求,获取登录后的Cookies。例如:
# tutorial/spiders/example_spider.py
import scrapy
from scrapy.http import FormRequest
from tutorial.items import QuoteItem
class ExampleSpider(scrapy.Spider):
name = 'example'
login_url = 'http://quotes.toscrape.com/login'
start_urls = [login_url]
def parse(self, response):
return FormRequest(
self.login_url,
formdata={'username': 'user', 'password': 'pass'},
callback=self.after_login
)
def after_login(self, response):
# 登录后访问需要登录才能访问的页面
yield scrapy.Request('http://quotes.toscrape.com/user', self.parse_user_page)
def parse_user_page(self, response):
for quote in response.css('div.quote'):
item = QuoteItem()
item['text'] = quote.css('span.text::text').get()
item['author'] = quote.css('span small::text').get()
item['tags'] = quote.css('div.tags a.tag::text').getall()
yield item
上述代码通过FormRequest
发送登录请求,获取登录后的Cookies,然后访问需要登录才能访问的页面。
处理Cookies
Scrapy默认不保存登录后的Cookies,可以使用中间件来处理Cookies。例如:
# tutorial/middlewares.py
from scrapy import signals
from scrapy.http import Request
class LoginMiddleware:
def process_request(self, request, spider):
# 获取登录后的Cookies
cookies = spider.cookies
if cookies:
request.cookies = cookies
return request
在settings.py
中启用中间件:
# tutorial/settings.py
DOWNLOADER_MIDDLEWARES = {
'tutorial.middlewares.LoginMiddleware': 543,
}
运行爬虫时,登录后的Cookies会被注入到后续请求中。
Scrapy爬虫部署Scrapy项目的部署方法
为了将Scrapy爬虫部署到生产环境,通常需要将其与Web应用框架(如Django、Flask)或任务调度器(如Celery)结合使用。以下是几种常见的部署方法:
使用Scrapy与Django集成
- 安装Django和Scrapy
- 创建Django项目和应用
- 在应用中导入Scrapy
- 创建Django管理命令来运行Scrapy爬虫
- 配置Django项目以运行Scrapy爬虫
以下是具体步骤:
-
安装Django和Scrapy
先确保已安装Python环境,然后使用pip安装Django和Scrapy:
pip install django scrapy
-
创建Django项目和应用
使用Django命令创建一个新的Django项目和应用:
django-admin startproject myproject cd myproject python manage.py startapp myapp
-
在应用中导入Scrapy
在
myapp
目录下创建一个scrapy.py
文件,并导入Scrapy:# myapp/scrapy.py import os import sys sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/..')) from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from scrapy.utils.log import configure_logging def run_spider(spider_name): configure_logging() process = CrawlerProcess(get_project_settings()) process.crawl(spider_name) process.start()
-
创建Django管理命令
在
myapp
目录下创建一个management/commands
文件夹,并在其中创建runspider.py
文件:# myapp/management/commands/runspider.py from django.core.management.base import BaseCommand from myapp.scrapy import run_spider class Command(BaseCommand): help = 'Run a Scrapy spider' def add_arguments(self, parser): parser.add_argument('spider_name', type=str) def handle(self, *args, **options): run_spider(options['spider_name'])
-
配置Django项目
修改
myproject/settings.py
文件,导入Scrapy设置:# myproject/settings.py import os from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings def run_spider(spider_name): configure_logging() process = CrawlerProcess(get_project_settings()) process.crawl(spider_name) process.start()
然后在
myproject/urls.py
中添加一个URL路由,用于启动爬虫:# myproject/urls.py from django.contrib import admin from django.urls import path from myapp.management.commands.runspider import Command urlpatterns = [ path('admin/', admin.site.urls), path('run-spider/<spider_name>/', Command().run, name='run_spider'), ]
使用Scrapy与Flask集成
- 安装Flask和Scrapy
- 创建Flask应用
- 在应用中导入Scrapy
- 创建Flask路由来启动Scrapy爬虫
- 配置Flask应用以运行Scrapy爬虫
以下是具体步骤:
-
安装Flask和Scrapy
使用pip安装Flask和Scrapy:
pip install flask scrapy
-
创建Flask应用
创建一个新的Flask应用,并在应用中导入Scrapy:
# myapp/app.py from flask import Flask from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from scrapy.utils.log import configure_logging app = Flask(__name__) def run_spider(spider_name): configure_logging() process = CrawlerProcess(get_project_settings()) process.crawl(spider_name) process.start() @app.route('/run-spider/<spider_name>') def run_spider_route(spider_name): run_spider(spider_name) return f'Spider {spider_name} started'
-
创建Flask路由
在
app.py
中创建一个Flask路由来启动Scrapy爬虫:@app.route('/run-spider/<spider_name>') def run_spider_route(spider_name): run_spider(spider_name) return f'Spider {spider_name} started'
-
配置Flask应用
在
app.py
中配置Flask应用以运行Scrapy爬虫:if __name__ == '__main__': app.run()
Scrapy爬虫的定时任务设置
为了定期执行Scrapy爬虫,可以使用任务调度器如Celery、APScheduler或简单的cron作业。以下是使用Celery和APScheduler的示例。
使用Celery
-
安装Celery和Scrapy
使用pip安装Celery和Scrapy:
pip install celery scrapy
-
创建Celery任务
创建一个新的Celery任务,并在任务中导入Scrapy:
# myapp/tasks.py from celery import Celery from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from scrapy.utils.log import configure_logging app = Celery('tasks', broker='redis://localhost:6379/0') @app.task def run_spider(spider_name): configure_logging() process = CrawlerProcess(get_project_settings()) process.crawl(spider_name) process.start()
-
配置Celery
在
myproject/settings.py
中配置Celery:# myproject/settings.py import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') app = Celery('myproject') app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks()
-
创建定时任务
在
myapp/tasks.py
中创建一个定时任务:from celery.schedules import crontab app.conf.beat_schedule = { 'run-spider-every-day': { 'task': 'myapp.tasks.run_spider', 'schedule': crontab(hour=12, minute=0), 'args': ('example',), }, }
使用APScheduler
-
安装APScheduler和Scrapy
使用pip安装APScheduler和Scrapy:
pip install apscheduler scrapy
-
创建APScheduler任务
创建一个新的APScheduler任务,并在任务中导入Scrapy:
# myapp/apscheduler.py from apscheduler.schedulers.blocking import BlockingScheduler from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from scrapy.utils.log import configure_logging scheduler = BlockingScheduler() @scheduler.scheduled_job('interval', hour=12, minute=0) def run_spider(): configure_logging() process = CrawlerProcess(get_project_settings()) process.crawl('example') process.start()
-
运行APScheduler
在
myapp/apscheduler.py
中运行APScheduler:if __name__ == '__main__': scheduler.start()
Scrapy爬虫的日志与监控
为了更好地管理和维护Scrapy爬虫,可以使用日志记录和监控工具。
日志记录
Scrapy默认使用Python的logging
模块来进行日志记录。可以通过修改settings.py
来调整日志级别和输出位置。例如:
# tutorial/settings.py
LOG_LEVEL = 'WARNING'
LOG_FILE = 'scrapy.log'
设置日志级别为WARNING
级别,并将日志输出到项目根目录下的scrapy.log
文件中。
监控
Scrapy自带的监控插件scrapy-redis
可以用于监控爬虫的运行情况。需要安装scrapy-redis
库:
pip install scrapy-redis
在settings.py
中启用scrapy-redis
:
# tutorial/settings.py
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_KEY = "your-duplicate-filter-key"
REDIS_URL = 'redis://localhost:6379/0'
这会将调度器和去重过滤器存储到Redis中,以便监控爬虫的运行情况。
Scrapy爬虫的常见问题与解决方案
在使用Scrapy过程中,可能会遇到一些常见问题,以下是一些常见的问题及其解决方案:
问题1:Scrapy爬虫抓取速度过快
如果抓取速度过快,可能会导致网站服务器拒绝服务(DDoS)。可以通过设置下载延迟来限制抓取速度:
# tutorial/settings.py
DOWNLOAD_DELAY = 1.0
问题2:爬虫被网站封杀
某些网站会检测爬虫行为,如果被检测到,可能会封杀IP地址。为了避免这种情况,可以使用代理IP:
# tutorial/settings.py
HTTP_PROXY = 'http://127.0.0.1:8111'
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 1,
}
问题3:抓取的数据不完整或错误
如果抓取的数据不完整或错误,可以通过修改解析规则来解决。例如,使用CSS选择器或XPath表达式提取正确的数据:
# tutorial/spiders/example_spider.py
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').extract(),
}
问题4:爬虫运行异常
如果爬虫运行时出现异常,可以通过查看日志文件来定位问题。可以通过设置日志级别为DEBUG
来获取详细的日志信息:
# tutorial/settings.py
LOG_LEVEL = 'DEBUG'
通过以上方法,可以有效管理和维护Scrapy爬虫,确保其稳定运行。
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章