在互联网数据采集领域,Scrapy框架以其强大的异步处理能力而著称。Scrapy利用了Python的异步网络请求库,如twisted
,来实现高效的并发数据采集。本文将深入探讨Scrapy框架的异步处理能力,并展示如何在当当网数据采集项目中应用这一能力。
1. Scrapy框架概述
Scrapy是一个快速的、高层次的web爬虫框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy的异步处理能力主要得益于其底层的twisted
异步网络库。
1.1 Scrapy架构
Scrapy的架构可以分为几个主要部分:
- 引擎(Engine):负责控制数据流在系统中的所有组件之间的流动,并在某些动作发生时触发事件。
- 爬虫(Spiders):负责解析响应并生成爬取的URL和/或提取数据(即Item)。
- 调度器(Scheduler):负责接收引擎发送的请求,并将其入队列以待之后处理。
- 下载器(Downloader):负责获取网页数据。
- 项目管道(Item Pipeline):负责处理爬虫从网页中抽取的数据。
- 下载器中间件(Downloader Middlewares):位于Engine和Downloader之间,主要是处理引擎与下载器之间的请求和响应。
- 爬虫中间件(Spider Middlewares):位于Engine和Spider之间,主要是处理蜘蛛的输入(响应)和输出(提取的数据,即Item)。
1.2 异步处理的优势
Scrapy的异步处理能力使得它能够在单个爬虫实例中同时处理多个请求和响应,这大大提高了数据采集的效率。异步处理的优势包括:
- 提高效率:并发处理多个请求,减少等待时间。
- 节省资源:相比多进程或多线程,异步IO使用更少的系统资源。
- 易于扩展:Scrapy的架构支持水平扩展,易于在多台机器上运行。
2. 实现当当网数据采集
首先,确保安装了Scrapy。
使用Scrapy创建一个新的项目:
在items.py
文件中定义当当网数据的结构。
编写爬虫
在spiders/doudang_spider.py
文件中编写爬虫:
import scrapy
from doudang_spider.items import DoudangBookItem
class DoudangSpider(scrapy.Spider):
name = 'doudang'
allowed_domains = ['dangdang.com']
start_urls = ['http://dangdang.com']
def __init__(self, *args, **kwargs):
super(DoudangSpider, self).__init__(*args, **kwargs)
self.proxy = 'http://{}:{}'.format(self.proxyHost, self.proxyPort)
self.auth = (self.proxyUser, self.proxyPass)
def parse(self, response):
for book in response.css('div.product'):
item = DoudangBookItem()
item['title'] = book.css('h3::text').get()
item['price'] = book.css('.price::text').get()
item['description'] = book.css('.description::text').get()
item['url'] = response.urljoin(book.css('a::attr(href)').get())
yield item
# 在 settings.py 中添加以下配置
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}
PROXY_HOST = 'www.16yun.cn'
PROXY_PORT = '5445'
PROXY_USER = '16QMSOML'
PROXY_PASS = '280651'
2.1 异步处理
Scrapy的异步处理主要通过twisted
库实现。在爬虫中,可以通过meta
传递消息给下一个请求,实现请求的异步处理:
python
def parse(self, response):
for book in response.css('div.product'):
# ... 省略其他代码
yield scrapy.Request(
url=item['url'],
callback=self.parse_book_detail,
meta={'item': item}
)
def parse_book_detail(self, response):
item = response.meta['item']
# 处理书籍详情
item['description'] = response.css('.detail-description::text').get()
yield item
3. 性能优化
3.1 并发设置
在settings.py
中设置并发请求的数量:
python
CONCURRENT_REQUESTS = 32
3.2 下载延迟
设置下载延迟,以避免对网站服务器造成过大压力:
python
DOWNLOAD_DELAY = 1.0 # 每秒请求一次
3.3 自动限制
Scrapy还提供了自动限制请求速率的功能:
python复制
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 5.0
AUTOTHROTTLE_MAX_DELAY = 60
关于文章代理有需要的小伙伴可以关注获取免费测试:https://v.16yun.cn/accounts/phone_register/?sale_user=ZM_seven7