Python爬虫-scrapy爬dangdang网

scrapy架构组成

(1)引擎 ‐‐‐》自动运行,无需关注,会自动组织所有的请求对象,分发给下载器
(2)下载器 ‐‐‐》从引擎处获取到请求对象后,请求数据
(3)spiders ‐‐‐》Spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例
如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。
(4)调度器 ‐‐‐》有自己的调度规则,无需关注
(5)管道(Item pipeline) ‐‐‐》最终处理数据的管道,会预留接口供我们处理数据当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。
以下是item pipeline的一些典型应用:

  1. 清理HTML数据
  2. 验证爬取的数据(检查item包含某些字段)
  3. 查重(并丢弃)
  4. 将爬取结果保存到数据库中

scrapy工作原理

在这里插入图片描述

yield

  1. 带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代
  2. yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行。

案例:

dangdang网url:‘http://category.dangdang.com/cp01.01.02.00.00.00.html’
在cmd创建项目
scrapy startproject scrapydangdang
创建爬虫文件

scrapy genspider dang http://category.dangdang.com/cp01.01.02.00.00.00.html

在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 ScrapydangdangItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    src = scrapy.Field()
    name=scrapy.Field()
    price=scrapy.Field()

给src、name、price做定位:
(在给图片做定位时发现网站做了懒加载,但是第一张图片没有做懒加载,所以用if语句给区分开)

import scrapy
from scrapydangdang.items import ScrapydangdangItem

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

    def parse(self, response):
#//ul[@class="bigimg"]/li//img/@src
#//ul[@class="bigimg"]/li//img/@alt
#//ul[@class="bigimg"]/li//span[@class="search_now_price"]
        li_list=response.xpath('//ul[@class="bigimg"]/li')
        for i in li_list:
            src=i.xpath('.//img/@data-original').extract_first()
            if src:
                src=src
            else:
                src=i.xpath('.//img/@src').extract_first()

            name=i.xpath('.//img/@alt').extract_first()
            price=i.xpath('.//span[@class="search_now_price"]').extract_first()

            book=ScrapydangdangItem(src=src,name=name,price=price)
            #获取一个book 就将一个book交给pipelines
            yield book

来到pipelines.py中使用管道下载:
(要使用管道时,要在settings.py中把ITEM_PIPELINES注释解掉)

ITEM_PIPELINES = {
   'scrapydangdang.pipelines.ScrapydangdangPipeline': 300,
}

这里是name、src、price三个数据下载到一个json文件中。

#settings开启管道
class ScrapydangdangPipeline:
    def open_spider(self,spider):
        self.fp=open('book.json','w',encoding='utf-8')
    #items就是yield后面的book对象
    def process_item(self, item, spider):

        self.fp.write(str(item))

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

这里不宜使用with open('book.json','a',encoding='utf-8')as fp:的形式,因为这种方法每传递一个对象就会打开一次文件,再关上一次文件,对文件的操作过于频繁。

为了提高下载速度,我们采用多条管道下载。
在settings.py中的ITEM_PIPELINES中加上:
(管道可以有很多个,而且有优先级,优先级范围是1-1000,值越小优先级越高)

ITEM_PIPELINES = {
   'scrapydangdang.pipelines.ScrapydangdangPipeline': 300,
   'scrapydangdang.pipelines.dangdangdownloadpipeline': 301,
}

然后在pipelines.py中定义管道类:
(这一步是下载图片)

import urllib.request
#'scrapydangdang.pipelines.dangdangdownloadpipeline': 301
class dangdangdownloadpipeline:
    def process_item(self, item, spider):
        url='http:'+item.get('src')
        filename='./books/'+item.get('name')+'.jpg'

        urllib.request.urlretrieve(url=url,filename=filename)

        return item

cmd中scrapy crawl dang就能启动了:
请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值