什么叫做深度爬取?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:
- scrapy startproject moviePro
- cd moviePro
- scrapy genspider movie www.xxx.com
- 修改配置文件
我们先来取出电影名称和详情页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