Python爬虫——scrapy_当当网图书管道封装

  1. 创建爬虫项目
srcapy startproject scrapy_dangdang
  1. 进入到spider文件里创建爬虫文件(这里爬取的是青春文学,仙侠玄幻分类)
srcapy genspider dang http://category.dangdang.com/cp01.01.07.00.00.00.html
  1. 获取图片、名字和价格
# 所有的seletor的对象,都可以再次调用xpath方法
li_list = response.xpath('//div[@id="search_nature_rg"]//li')

for li in li_list:
	# 获取图片
    src = li.xpath('.//img/@data-original').extract_first()
    # 第一张图片和其他图片的标签的属性不一样
    # 第一张图片的src是可以使用的,其他图片的地址在data-original里
    if src:
    	src = src
    else:
        src = li.xpath('.//img/@src').extract_first()
    # 获取名字
    name = li.xpath('.//img/@alt').extract_first()
    # 获取价格
    price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
    
    print(src, name, price)
  1. 在items里定义要下载的数据
import scrapy


class ScrapyDangdang39Item(scrapy.Item):
    # 要下载的数据都有什么
    # 图片
    src = scrapy.Field()
    # 名字
    name = scrapy.Field()
    # 价格
    price = scrapy.Field()
  1. 在dang.py里导入items
from ..items import ScrapyDangdang39Item
  1. 在parse方法里定义一个对象book,然后把获取到的值传递到pipelines
book = ScrapyDangdang39Item(src=src, name=name, price=price)

# 获取一个book就将book传递给pipelines
yield book
  1. 开启管道
    在settings中,把这几行代码取消注释
    在这里插入图片描述
    管道可以有很多个,但是管道是有优先级的,优先级的范围是1到1000 值越小,优先级越高
  2. 下载数据
    打开piplines.py
class ScrapyDangdang39Pipeline:
    # 方法1
    # 在爬虫文件执行前执行的一个方法
    def open_spider(self, spider):
        self.fp = open('book.json', 'w', encoding='utf-8')


    def process_item(self, item, spider):
        # item就是yield后面的book对象
        
        # 1.write方法必须要写一个字符串,而不是其他的对象
        # 2.w模式,每一个对象都会打开一次文件,然后覆盖之前的内容,所以使用a模式
        with open('book.json', 'a', encoding='utf-8')as fp:
        	fp.write(str(item))
        	
        return item

但是这种模式不推荐,因为每传递过来一个数据,就要打开一次文件,对文件的操作太过频繁
换一种方法

class ScrapyDangdang39Pipeline:
    # 在爬虫文件执行前执行的一个方法
    def open_spider(self, spider):
        self.fp = open('book.json', 'w', encoding='utf-8')


    def process_item(self, item, spider):
        # item就是yield后面的book对象
        
        self.fp.write(str(item))

        return item

    # 在爬虫文件执行完后执行的一个方法
    def close_spider(self, spider):
        self.fp.close()
  1. 运行dang.py文件就可以把数据保存到本地了

完整代码
dang.py

import scrapy
from ..items import ScrapyDangdang39Item


class DangSpider(scrapy.Spider):
    name = "dang"
    allowed_domains = ["category.dangdang.com"]
    start_urls = ["http://category.dangdang.com/cp01.01.07.00.00.00.html"]

    def parse(self, response):
        # 所有的seletor的对象,都可以再次调用xpath方法
        li_list = response.xpath('//div[@id="search_nature_rg"]//li')

        for li in li_list:
            # 获取图片
            src = li.xpath('.//img/@data-original').extract_first()
            # 第一张图片和其他图片的标签的属性不一样
            # 第一张图片的src是可以使用的,其他图片的地址在data-original里
            if src:
                src = src
            else:
                src = li.xpath('.//img/@src').extract_first()
            # 获取名字
            name = li.xpath('.//img/@alt').extract_first()
            # 获取价格
            price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()

            book = ScrapyDangdang39Item(src=src, name=name, price=price)

            # 获取一个book就将book传递给pipelines
            yield book

items.py

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class ScrapyDangdang39Item(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()

    # 要下载的数据都有什么
    # 图片
    src = scrapy.Field()
    # 名字
    name = scrapy.Field()
    # 价格
    price = scrapy.Field()

pipelines.py

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter

# 如果想使用管道,就必须在settings中开启管道
class ScrapyDangdang39Pipeline:
    # 方法1
    # 在爬虫文件执行前执行的一个方法
    def open_spider(self, spider):
        self.fp = open('book.json', 'w', encoding='utf-8')


    def process_item(self, item, spider):
        # item就是yield后面的book对象

        # 这种模式不推荐
        # with open('book.json', 'a', encoding='utf-8')as fp:
        #     fp.write(str(item))

        self.fp.write(str(item))

        return item

    # 在爬虫文件执行完后执行的一个方法
    def close_spider(self, spider):
        self.fp.close()

你可能感兴趣的:(Python爬虫,python,爬虫,scrapy)