爬虫工作量由小到大的思维转变---<第七章 Scrapy超越控制台===代码运行scrapy+多线程爬取+数据交互>
2023-12-14 22:37:53
前言:
?针对留言的问题:
????????scrapy谁告诉你只能在控制台启动的?你是抖和BILI看多了吧!!
? ? ? ? ?? ?- ? ?---看我的,让你玩出花;
正文:
传统方式 vs 脚本方式
在Scrapy框架中,传统方式一般是指通过终端(或命令行)启动Scrapy项目,而脚本方式是指在Python环境中直接运行一个或多个Scrapy爬虫。
传统方式:
- 命令行启动: 通过运行scrapy crawl spidername在终端或命令提示符中启动爬虫。
- 配置分散: 命令行参数和项目的settings.py文件分散配置。
- 单一进程: 一次通常只能运行一个爬虫,且运行多个爬虫需要多个终端窗口。
- 输出受限: 数据通常输出到预设位置,改变输出需修改设置或使用指令参数。
脚本方式:
- Python脚本启动: 通过创建一个Python脚本,使用Scrapy API来配置和运行爬虫。
- 集中配置: 脚本中统一设置,包括爬虫参数和自定义设置。
- 并发运行: 同一个脚本中可以配置和运行多个爬虫实例,实现并行爬取。
- 灵活输出: 数据可以在脚本中按需处理,并动态指定输出位置。
案例:
# Python脚本内部运行Scrapy
from scrapy.crawler import CrawlerProcess
from myproject.spiders.spider_one import SpiderOne
from myproject.spiders.spider_two import SpiderTwo
process = CrawlerProcess(get_project_settings())
# 定时运行不同的爬虫
process.crawl(SpiderOne)
process.crawl(SpiderTwo)
# 开始爬取
process.start() # 脚本会在这里阻塞直到所有爬虫执行完毕
# 爬取完成后,例如,发送邮件通知或生成报告
send_email_notification()
generate_report()
在此案例中,两个爬虫SpiderOne和SpiderTwo会并发执行,它们各自独立工作,不共享数据或状态。
实现多线程/多实例爬虫
?????Scrapy框架提供了良好的支持,但对于大规模数据采集任务,引入多线程和多实例运行可以显著提升数据爬取效率
虽然CrawlerProcess在单个进程中管理多个爬虫,使用Python的多线程或多进程库可以实现更高级别的并发。这允许每个爬虫在自己的进程或线程中运行,有利于CPU密集型或I/O密集型的任务。
多线程案例:
from threading import Thread
from scrapy.crawler import CrawlerRunner
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
runner = CrawlerRunner(settings)
def run_spider(spider):
runner.crawl(spider)
runner.join()
# 启动线程以运行爬虫
thread1 = Thread(target=run_spider, args=(SpiderOne,))
thread2 = Thread(target=run_spider, args=(SpiderTwo,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
多进程案例:
from multiprocessing import Process
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
def run_spider(spider):
process = CrawlerProcess(get_project_settings())
process.crawl(spider)
process.start()
# 创建并启动进程
process1 = Process(target=run_spider, args=(SpiderOne,))
process2 = Process(target=run_spider, args=(SpiderTwo,))
process1.start()
process2.start()
process1.join()
process2.join()
在讨论多线程和多进程时,应注意Python的全局解释器锁(GIL)限制,它使得真正的并行只能在多进程中实现,而非多线程。对于CPU密集型任务,应优先选择多进程来提高效率。然而,Scrapy以I/O操作为主,因此通常情况下,使用多线程或CrawlerProcess就已经足够。
小总结:
通过结合Scrapy的CrawlerProcess和Python的多线程/多进程技术,开发者可以为他们的应用构建一个强大的爬虫集群,实现高效的数据采集。在数据采集的世界中,这种能力是无价的,可以显著减少采集时间,同时提取大量信息。
交互性扩展
? 为了提升Scrapy爬虫的适用性和灵活性,有时需要在运行时传递参数,或者处理爬虫返回的数据!Scrapy支持在启动爬虫时传递参数,这对于需要根据不同条件抓取页面的情况非常有用。
案例:
假设我们有一个爬虫需要根据用户输入的关键词搜索数据:
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from myproject.spiders import MySpider
process = CrawlerProcess(get_project_settings())
# 运行爬虫,并将关键词作为参数传递
keyword = 'python'
process.crawl(MySpider, keyword=keyword)
process.start()
在上面的脚本示例中,我们通过crawl方法传递了一个关键字参数到爬虫。在爬虫中,你可以通过__init__方法访问这个参数。
import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
def __init__(self, keyword=None, *args, **kwargs):
super(MySpider, self).__init__(*args, **kwargs)
self.keyword = keyword # 使用传递的关键词
def start_requests(self):
url = f'http://search.example.com/?q={self.keyword}'
yield scrapy.Request(url, self.parse)
def parse(self, response):
# 爬虫的解析逻辑
pass
从爬虫获取并处理数据
Scrapy爬虫可以将抓取到的数据作为Items返回。然后,这些Items可以在Pipeline中进一步处理。如果需要在脚本中直接处理数据,可以在爬虫中捕获这些数据并将其返回。
import scrapy
from scrapy.crawler import CrawlerRunner
from scrapy import signals
from twisted.internet import reactor
from scrapy.utils.project import get_project_settings
class MySpider(scrapy.Spider):
# ... 其他代码 ...
def parse(self, response):
# 解析逻辑,提取数据
yield {'url': response.url}
def item_collected(item):
print(item['url']) # 打印或处理Item
runner = CrawlerRunner(get_project_settings())
def crawl_job():
spider = MySpider(keyword='python')
deferred = runner.crawl(spider)
deferred.addBoth(lambda _: reactor.stop()) # 当爬虫结束时停止reactor
runner.signals.connect(item_collected, signal=signals.item_scraped)
reactor.run() # 启动事件循环
crawl_job()
在crawl_job函数中,我们创建了一个爬虫实例并启动了爬虫,同时连接了一个信号处理函数item_collected到item_scraped信号。每当有Item被抓取时,该信号被触发,执行item_collected函数。
小总结:
通过Scrapy提供的接口和信号系统,我们可以灵活地在运行时传递参数给爬虫,以及在脚本中处理爬虫收集的数据。这两个特性极大地增强了Scrapy的交互性,使其不仅可以在终端运行,而且可以作为Python项目的一部分,与其他组件相集成。
这种增强的交互性特别适合构建复杂的爬取任务,如定时任务、条件抓取、数据后处理、实时分析等。
文章来源:https://blog.csdn.net/m0_56758840/article/details/135004903
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!