学习目标
1 通过一个案例改成成scrapy_redis 当当网
2 案例练习 小说 盗墓笔记
当当网 http://book.dangdang.com/ 思路:先实现普通的scrapy爬虫,然后在改写成scrapy_redis **第一步 页面分析** 需求:大分类 二级分类 三级分类 图书的名字和图片的src 大分类 整个大分类都在 div con flq_body 它下面的 div/dl/dt 注意:1 在大分类中有一个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() 注意:图片的src images/model/guan/url_none.png 这个时候还是要看下源码 data-original="http://img3m0.ddimg.cn/95/11/27854240-1_b_14.jpg" **第二步 实现步骤** 1 创建scrapy项目(爬虫) 2 分析页面并实现逻辑 3 改写程序(scrapy_redis)
改写成scrapy-redis:
爬虫文件: 1 模块 from scrapy_redis.spiders import RedisSpider 2 继承的父类 RedisSpider 3 把start_urls 改写成 reids_key='爬虫文件名字' settings文件 # 去重过滤 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # scheduler队里 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 数据持久化 SCHEDULER_PERSIST = True ITEM_PIPELINES = { #'example.pipelines.ExamplePipeline': 300,(这个不能有) 'scrapy_redis.pipelines.RedisPipeline': 400, }
接着 cmd中:LPUSH dangdang http://book.dangdang.com/
源码:
(day25)
import scrapy from copy import deepcopy from scrapy_redis.spiders import RedisSpider # 第一步 class DangdangSpider(RedisSpider):# 第二步 name = 'dangdang' allowed_domains = ['dangdang.com'] # start_urls = ['http://book.dangdang.com/'] reids_key = 'dangdang' # 第一三步 def parse(self, response): first_type=response.xpath('//div[@class="con flq_body"]/div') # a=0 for type in first_type : #获得大分类 item={} item['first_type_name']=type.xpath('./dl/dt//text()').getall() item['first_type_name']=[i.strip() for i in item['first_type_name'] if len(i.strip())>0]#这一步是由调试得来的 # print(item) # a+=1 # print(a) second_type= type.xpath('.//dl[@class="inner_dl"]') for type1 in second_type: #获取中分类 item['second_type_name'] = type1.xpath('./dt//text()').getall()#尽量用//text(),获得列表 item['second_type_name'] = [i.strip() for i in item['second_type_name'] if len(i.strip()) > 0] # print(item) #获取小分类 third_type = type1.xpath('.//a') for type2 in third_type: item['third_type_name'] = type2.xpath('./text()').get() item['link'] = type2.xpath('./@href').get() if item['link'] is not None: yield scrapy.Request( url=item['link'], callback=self.parse_book_list, meta={'item':deepcopy(item)} ) # print(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: item['title'] = li.xpath('./a[@class="name"]/a/@title').get() item['address'] = 'images/model/guan/url_none.png' if item['address'] == 'images/model/guan/url_none.png': item['address'] = li.xpath('./a[@class="img"]/img/@data-original').get() # print(item) yield item
注意:
1 拷贝的方式:
2 LOG_LEVEL=‘WARNING’:
表示若日志有错误,则打印,否则不打印
第一步 页面分析 一级页面 a_list //li[contains(@id,"menu-item-")]/a 大章节的标题 ./text() 章节的链接 ./@href 二级页面 a_list //article/a 小章节的标题 ./text() 小章节的链接 ./@href 三级页面 小说内容 //article/p/text() ['段落1','段落2'.....] '\n'.join(['段落1','段落2'.....]) 第二步 实现步骤 注意: 利用meta参数在进行不同的解析方法之间传递数据的时候 如果需要继续的交给调度器去请求 1 用deepcopy 2 创建新的item对象