赞
踩
一、scrapy_redis案例之爬取 当当网
整体思路:先实现普通的scrapy爬虫,然后在改写成scrapy_redis
普通的scrapy爬虫:
(一)需求:获取图书分类中所有图书的书名和封面,如下图:
也就是说先得到小分类中的链接,点击(请求)进入之后,再获取每本书的书名和封面(链接)
(二)页面分析:
1、右键查看网页源代码,发现数据就在源代码中,不是js。
(三)爬虫文件的实现:
1、新建爬虫项目:(在桌面,新建一个dangd的爬虫文件夹)
2、点击进入爬虫文件夹,打开爬虫文件:
3、将逻辑代码写入该文件:
逻辑:大分类 二级分类 三级分类 图书的名字和图片的src
# -*- coding: utf-8 -*- import scrapy class DangdangSpider(scrapy.Spider): name = 'dangdang' allowed_domains = ['dangdang.com'] start_urls = ['http://book.dangdang.com/'] #将['http://dangdang.com/']修改 def parse(self, response): div_list = response.xpath('//div[@class="con flq_body"]/div') for div in div_list: item = {} # 获取大分类 item['b_cate'] = div.xpath('./dl/dt//text()').extract() item['b_cate'] = [i.strip() for i in item['b_cate'] if len(i.strip())>0] dl_list = div.xpath('.//dl[@class="inner_dl"]') for dl in dl_list: # 获取中分类 item['m_cate'] = dl.xpath('./dt//text()').extract() item['m_cate'] = [i.strip() for i in item['m_cate'] if len(i.strip()) > 0] # 获取小分类 a_list = dl.xpath('./dd/a') for a in a_list: item['s_cate'] = a.xpath('./text()').extract_first() item['s_href'] = a.xpath('./@href').extract_first() print(item)
注意:
大分类
整个大分类都在 div con flq_body 它下面的 div/dl/dt
(1)在大分类中有一个span标签,
但是源码中没有,
如果写成:
item[‘b_cate’] = div.xpath(’./dl/dt/span/text()’).extract(),反而是空。所以就不要span。
(2) 有的大分类在dt标签下面还有一个a标签,所以用双斜杠//, /dt//text().extract()
补充:单斜杠/和双斜杠//的区别:
二级分类
div level one --> dl class=“inner_dl” dt/text()
(1)有的大分类在dt标签下面还有一个a标签 /dt//text().extract()
三级分类
dl class=“inner_dl” --> dd/a/text()
(1)右键检查,定位到的src,以获取封面图片;与右键网页源代码中的src,不一致的问题。(后面有详细说明)
4、settings文件的准备:
LOG_LEVEL = 'WARNING'
ROBOTSTXT_OBEY = False
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
5、在cmd中进入到爬虫文件夹后,运行爬虫文件:scrapy crawl 爬虫文件名
结果:
由此就得到了小分类中的链接,接下来就是要请求这些链接,并获取每本书的书名和封面(链接)
6、请求和解析
# -*- coding: utf-8 -*- import scrapy from copy import deepcopy class DangdangSpider(scrapy.Spider): name = 'dangdang' allowed_domains = ['dangdang.com'] start_urls = ['http://book.dangdang.com/'] #将['http://dangdang.com/']修改 def parse(self, response): div_list = response.xpath('//div[@class="con flq_body"]/div') for div in div_list: item = {} # 获取大分类 item['b_cate'] = div.xpath('./dl/dt//text()').extract() item['b_cate'] = [i.strip() for i in item['b_cate'] if len(i.strip())>0] dl_list = div.xpath('.//dl[@class="inner_dl"]') for dl in dl_list: # 获取中分类 item['m_cate'] = dl.xpath('./dt//text()').extract() item['m_cate'] = [i.strip() for i in item['m_cate'] if len(i.strip()) > 0] # 获取小分类 a_list = dl.xpath('./dd/a') for a in a_list: item['s_cate'] = a.xpath('./text()').extract_first() item['s_href'] = a.xpath('./@href').extract_first() if item['s_href'] is not None: yield scrapy.Request( url=item['s_href'], callback=self.parse_book_list, meta={'item':deepcopy(item)} ) #print(item) #这里的打印item,结果不包含书名和封面 def parse_book_list(self,response): item = response.meta.get('item') li_list = response.xpath('//ul[@class="list_aa "]/li') for li in li_list: # 图片的url item['book_img'] = li.xpath('./a[@class="img"]/img/@data-original').extract_first() # 数据的名字 item['book_name'] = li.xpath('./p[@class="name"]//text()').extract_first() print(item) #这里的打印item,结果包含书名和封面
注意:在获取封面的时候,本身应该是定位到src属性值:
item['book_img'] = li.xpath('./a[@class="img"]/img/@src').extract_first()
但,得到的所有结果都是: images/model/guan/url_none.png,因为在网页源代码中,src都是一样的,
同时,我们发现data-original属性值,就是封面,所以就改为获取该属性。
结果:
如果需要保存,则相应在管道文件中编写。
补充:赋值号、复制和深复制
赋值号:
复制:
深复制:(下图和上图对比,并看不出来复制和深复制的不一样)
那么如何看出两者的不同?如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。