快捷搜索:

什么叫做深度爬取?Python爬虫:scrapy请求传参实现的深度爬取

 

概念和方式

深度爬取:爬取的数据没有在同一张页面中(首页数据+详情页数据)

在scrapy中如果没有请求传参,我们无法持久化存储数据

实现方式:

  • scrapy.Request(url,callback,meta)

meta是一个字典,可以将meta传递给callback

  • callback取出meta:

response.meta['item']


例程

爬取某电影网的电影名称和详情页的电影介绍

http://www.4567kp.com/frim/index1.html

这个网站首页和详情介绍不在同一页面,利用requests很容易爬取,但用scrapy必须要用到深度爬取

创建一个工程moviePro:

  1. scrapy startproject moviePro
  2. cd moviePro
  3. scrapy genspider movie www.xxx.com
  4. 修改配置文件

我们先来取出电影名称和详情页URL:

import scrapy class MovieSpider(scrapy.Spider): name = 'movie' # allowed_domains = ['www.xxx.com'] start_urls = ['http://www.4567kp.com/frim/index1.html'] def parse(self, response): li_list = response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li') for li in li_list: # 获取电影名称 title = li.xpath('./div/a/@title').extract_first() # 详情页URL detail_url = 'http://www.4567kp.com' + li.xpath('./div/a/@href').extract_first() print(title, detail_url)

运行一下:scrapy crawl movie

上节课我们讲了如果对新网站进行手动爬取:

那我们就可以对该电影网进行详情页的爬取:

yield scrapy.Request(url=detail_url,callback=)

但我们遇到一个问题:callback=?,这里肯定不能写self.parse。我们可以再写个函数进行详情页的数据解析:

# yield scrapy.Request(url=detail_url, callback=parse_detail) # 被作用于解析详情页的数据 def parse_detail(self, response): desc = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[3]').extract_first() ... yield ...

先别着急省略的代码。上面我们获取了电影名称和详情页数据,我们需要管道做持久化存储的话,需要定义item

items.py文件:

import scrapy class MovieproItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title = scrapy.Field() desc = scrapy.Field()

那我们就把item写进代码中:

def parse(self, response): li_list = response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li') for li in li_list: # 获取电影名称 title = li.xpath('./div/a/@title').extract_first() detail_url = 'http://www.4567kp.com' + li.xpath('./div/a/@href').extract_first() item = MovieproItem() item['title'] = title yield scrapy.Request(url=detail_url, callback=self.parse_detail) # 被作用于解析详情页的数据 def parse_detail(self, response): desc = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[3]').extract_first() item['desc'] = desc

但是,这样的话肯定是报错的。因为parse_detail函数中并没有item,这时候,我们就需要用到请求传参:

def parse(self, response): li_list = response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li') for li in li_list: # 获取电影名称 title = li.xpath('./div/a/@title').extract_first() detail_url = 'http://www.4567kp.com' + li.xpath('./div/a/@href').extract_first() item = MovieproItem() item['title'] = title # meta的作用:可以将mate字典传递给callback yield scrapy.Request(url=detail_url, callback=self.parse_detail, meta={'item': item}) # 被作用于解析详情页的数据 def parse_detail(self, response): # 接收传递过来的mate item = response.meta['item'] desc = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[3]').extract_first() item['desc'] = desc # 传递给管道 yield item

管道文件中打印下:

class MovieproPipeline: def process_item(self, item, spider): print(item) return item

我们来运行一下吧:

这样就爬取到了数据!

关注Python涛哥!学习更多Python知识!

[注:本文部分图片来自互联网!未经授权,不得转载!每天跟着我们读更多的书]


互推传媒文章转载自第三方或本站原创生产,如需转载,请联系版权方授权,如有内容如侵犯了你的权益,请联系我们进行删除!

如若转载,请注明出处:http://www.hfwlcm.com/info/70652.html