scrapy入门笔记(2)--当当热销月榜数据

目标:通过scrapy爬取当当网热销月榜所有页面数据

新学:xpath解析数据,多页下载,(多)管道下载,管道封装

url = "http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-%s"%(page)

page===>1~25

所需数据{书名,作者,出版社,价格,图片链接}

对应xpath:

name://div[@class="bang_list_box"]/ul/li/div[@class="name"]/text()
author://div[@class="bang_list_box"]/ul/li/div[@class="publisher_info"][1]/a[1]/text()
press://div[@class="bang_list_box"]/ul/li/div[@class="publisher_info"][2]/a[1]/text()
price://div[@class="bang_list_box"]/ul/li/div[@class="price"]/p[1]/span[1]/text()
src://div[@class="bang_list_box"]/ul/li/div[@class="pic"]/a/img/@src

爬虫文件:

import scrapy


class DangdangbookSpider(scrapy.Spider):
    name = 'dangdangbook'
    allowed_domains = []
    start_urls = ['http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-1']
    page = 1
    base_url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-%s'
    def parse(self, response):
        msg_dict = {}
        msg_list = response.xpath('//div[@class="bang_list_box"]/ul/li')
        for msg in msg_list:
            msg_dict['name'] = msg.xpath('./div[@class="name"]/a/text()').extract_first()
            msg_dict['author'] = msg.xpath('./div[@class="publisher_info"][1]/a[1]/text()').extract_first()
            msg_dict['press'] = msg.xpath('./div[@class="publisher_info"][2]/a[1]/text()').extract_first()
            msg_dict['price'] = msg.xpath('./div[@class="price"]/p[1]/span[1]/text()').extract_first()
            msg_dict['src'] = msg.xpath('./div[@class="pic"]/a/img/@src').extract_first()
            yield msg_dict

        if self.page<25:
            self.page+=1
            url = self.base_url%(self.page)
            yield scrapy.Request(url=url,callback=self.parse)

分析:

  1. 得到所有数据列表逐个提取数据为json保存在msg_dict中
  2. yield msg_dict  迭代器,每次遍历会将得到的该字典传给管道文件进行下载,直到一页遍历结束
  3. 至此,已经完成第一页的下载,self.page 自动加1直到第25页,url随之变化
  4. 发生变化后,回调parse函数,scrapy.Request(url=url,callback=self.parse),实现多页下载

管道文件:pinlines.py

import json
import urllib.request

from itemadapter import ItemAdapter


class DangdangbookPipeline:
    def open_spider(self,spider):
        self.fp = open("dd_sell_well_books.json","w",encoding="utf-8")


    def process_item(self, item, spider):
        self.fp.write(str(item))
        return item

    def close_spider(self,spider):
        self.fp.close()

class DangDangImgPipeline:
    def process_item(self, item, spider):
        url = item.get("src")
        filename = 'dd_imgs/' + item.get("name").replace("/","-") + '.jpg'
        urllib.request.urlretrieve(url=url,filename=filename,)
        return item

分析:

  1. 参数item即为爬虫文件传来的值,即上面的 yield msg_dict
  2. 本来默认只有函数process_item,为了重复开闭文件(I/O),定义open_spider(self,spider)和close_spiders(self,spider),起到管道封装作用
  3. 两个函数均需要传入spider参数
  4. open_spider在开启爬虫前被执行,这里用来开启前将文件打开,以便多次重复写入
  5. close_spider在关闭爬虫时被执行,这里用来爬取结束时自动关闭文件
  6. 本来默认的生成的类只有DangdangbookPipeline,这里为了学习多管道下载,创建一个管道DangDangImgPipeline用于下载src的图片,创建新管道的方法仿照默认类即可
  7. 将下载的图片另存在dd_imgs文件夹中,图片以name+jpg命名,path="dd_imgs/"+name+"jpg"
  8. 防止name中有"/"导致路径不存在===>item.get("name").replace("/","-")
  9. 下载图片直接使用urllib库,urllib.request.urlrettieve(url=url,filename=filename)
  10. 想要能通过管道下载文件,需将settings.py的ITEM_PIPELINES字典的注释去掉,如下
  11. 想通过多管道下载,需在settings.py的ITEM_PIPELINES字典添加'DangDangBook.pipelines.DangDangImgPipeline':301,即项目名称.piplines.新创建的类:优先级

settings.py

ITEM_PIPELINES = {
   'DangDangBook.pipelines.DangdangbookPipeline': 300,
   'DangDangBook.pipelines.DangDangImgPipeline':301,
}

说明:优先级即管道下载的优先顺序,从1~1000,越小越优先 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值