Scrapy的五大核心组件
在进行请求传参之前,可以先了解一下Scrapy的核心组件,可以更清楚的其运行流程
Scrapy是一个用于Web爬取的Python框架,它包含了五个核心组件,分别是:
引擎(Engine):引擎是Scrapy的核心组件,负责控制整个爬取流程的启动、停止和调度。它接收请求(Request)并将其分配给调度器(Scheduler)、下载器(Downloader)和爬虫(Spider)。
调度器(Scheduler):调度器是负责接收引擎传递过来的请求,并根据一定的策略将请求入队列,并在适当的时候将请求弹出队列,交给下载器进行下载。调度器可以实现请求去重和优先级管理。
下载器(Downloader):下载器负责下载引擎传递过来的请求对应的网页内容,并将下载好的响应(Response)返回给引擎。下载器可以处理各种网络协议、重试请求、处理重定向和cookies等。
爬虫(Spider):爬虫是用于解析网页内容和提取数据的组件。它定义了网页的下载方式、如何从网页中提取数据、如何跟进其他链接等。爬虫还可以生成新的请求,并将其返回给引擎。
项目管道(Pipeline):项目管道是用于处理从爬虫中提取出来的数据的组件。它负责对数据进行处理、清洗、去重等操作,并将最终的数据存储到指定的位置,如数据库、文件等。项目管道可以根据需要进行配置,可以启用多个管道组件,以实现不同的数据处理需求。
这些核心组件共同协作,使得Scrapy能够高效、灵活地进行网页爬取,并将爬取到的数据进行处理和存储。
请求传参
当我们爬取解析的数据不在同一张的页面的时候,就需要使用到请求传参,整个过程也叫深度爬取,以下是在python中利用scrapy进行的深度爬取案例
首先,创建Scrapy的基本组件,在命令行运行scrapy startproject project_name
命令来创建一个Scrapy项目
然后运行scrapy genspider spider_name website.com
命令来创建一个Spider
在settings.py文件中设置基本的参数
LOG_LEVEL='ERROR' USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0" ROBOTSTXT_OBEY = False
然后指定需要深度爬取的网站url,我选择爬取一个旅游网站各景点的标题和其里边的详细信息
import scrapy from thirdBlood.items import ThirdbloodItem # from thirdBlood.items import ImagedownloadItem class ThirdSpider(scrapy.Spider): name = "third" allowed_domains = ["www.baidu.com"] start_urls = ["https://www.szcits.cn/theme/hot_spring/"]
然后去定位主页面的标题所在位置
通过循环和标签的定位拿到首页里边详情页的url和标题
class ThirdSpider(scrapy.Spider): name = "third" allowed_domains = ["www.baidu.com"] start_urls = ["https://www.szcits.cn/theme/hot_spring/"] def parse(self, response): li_list=response.xpath('//*[@id="bigbox"]/section') for li in li_list: li_name=li.xpath('./div[2]/h3/a/text()').extract_first() detail_url=li.xpath('./div[1]/a/@href').extract_first() detail_url="https://www.szcits.cn"+detail_url
接下来就是请求传参的部分了,写一个parse_detail()用于处理详细页面的数据,通过scrapy.Request()去发起对详情页的请求,callback回到parse_detail()方法去爬取详情页的数据
class ThirdSpider(scrapy.Spider): name = "third" allowed_domains = ["www.baidu.com"] start_urls = ["https://www.szcits.cn/theme/hot_spring/"] def parse_detail(self, response): src=response.xpath('//*[@id="area1"]/div/div/p[1]/img/@data-src').extract_first() src="https://www.szcits.cn/"+src def parse(self, response): li_list=response.xpath('//*[@id="bigbox"]/section') for li in li_list: li_name=li.xpath('./div[2]/h3/a/text()').extract_first() detail_url=li.xpath('./div[1]/a/@href').extract_first() detail_url="https://www.szcits.cn"+detail_url yield scrapy.Request(url=detail_url,callback=self.parse_detail,dont_filter=True)
为了利用scrapy高效性,创建item提交到管道去解析数据
def parse(self, response): li_list=response.xpath('//*[@id="bigbox"]/section') for li in li_list: item=ThirdbloodItem() li_name=li.xpath('./div[2]/h3/a/text()').extract_first() item['li_name']=li_name detail_url=li.xpath('./div[1]/a/@href').extract_first() detail_url="https://www.szcits.cn"+detail_url yield scrapy.Request(url=detail_url,callback=self.parse_detail,dont_filter=True,meta={'item':item})
注意yield中要返回本次创建的item对象给parse_detail()方法,meta={''item'':item}
def parse_detail(self, response): item=response.meta['item'] src=response.xpath('//*[@id="area1"]/div/div/p[1]/img/@data-src').extract_first() src="https://www.szcits.cn/"+src item['src']=src yield item
items.py文件中item所需要的储存的变量
import scrapy class ThirdbloodItem(scrapy.Item): # define the fields for your item here like: li_name = scrapy.Field() src = scrapy.Field() # pass
在pipelines.py管道文件中接收并输出爬取的数据
class ThirdbloodPipeline: def process_item(self, item, spider): print("标题:"+item['li_name']) print("图片路径:"+item['src']) return item
并在setting文件中打开管道类
ITEM_PIPELINES = { "thirdBlood.pipelines.ThirdbloodPipeline": 300 }
最后,在命令行中输入scrapy crawl ’‘项目名’‘,就能进行深度爬取了