当前位置: 首页 > article >正文

scrapy案例——当当网的爬取二

 项目名称:当当网的爬取一——爬取科幻小说的书籍数据

案例需求:

1.使用scrapy爬虫技术爬取当当网中科幻小说的书籍数据,包括(图片、标题、作者和价格)

2.将获取到的数据保存在本地josn文件中

3.将图片保存在本地文件夹中

4.实现分页爬取

分析

1.数据包的获取

2.准备工作:

# ROBOTSTXT_OBEY = True
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
#开启管道
ITEM_PIPELINES = {
    #管道可以有很多个,因此管道有优先级  范围1-1000    值越小优先级越高
   'scrapy_dangdang.pipelines.ScrapyDangdangPipeline': 300,
   #DangDangDownloadPipeline
   'scrapy_dangdang.pipelines.DangDangDownloadPipeline': 302,
}

3.解析数据

同理

标题:
//ul[@id="component_59"]/li/a/img/@alt
同理:

价格:
//ul[@id="component_59"]/li/p[@class="price"]/span[1]/text()
作者:
//ul[@id="component_59"]/li/p[@class="search_book_author"]/span[1]/a[1]/text()

图片:
//ul[@id="component_59"]/li/a/img/@src
 #当当网爬取数据——科幻小说:图片、名字、价格
        li_list=response.xpath('//ul[@id="component_59"]/li')
        # url='http://'+response.xpath('/html/body/div[2]/div/div[3]/div[1]/div[1]/div[2]/div/ul/li/a/img/@src').extract()
        # for li,urls in zip(li_list,url):
        for li in li_list:
            src=li.xpath('.//img/@data-original').extract_first()
            # 第一张图片和其他图片的标签属性是不一样的   第一张图片的src是可以使用的,其他图片的地址是data-original'
            if src:
                src='http:'+src
            else:
                src = 'http:'+li.xpath('.//img/@src').extract_first()
            # src = urls
            # src = 'http//:' + li.xpath('.//img/@src').extract()
            name = li.xpath('.//img/@alt').extract_first()
            price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
            author=li.xpath('.//p[@class="search_book_author"]/span[1]/a[1]/text()').extract_first()
            print('标题:',name)
            print('作者:',author)
            print('价格:',price)
            print('图片:',src)
            print('=======================================')
            #print(src,name,price)#列表——改动:.extract_first()   图片都一样——懒加载,将src变成data-original
            #第一张图片地址为None,因为它没有data-original这个参数

            #当当网管道封装
            boook=ScrapyDangdangItem(src=src,name=name,price=price,author=author)
            #将上面爬取的数据交给pipelines下载
            # yield带有yield的函数不再是 - 个普通函数,而是一个生成器generator,可用于迭代
            # yield是 - 个类似return的关键字,迭代 - -次遇到yield时就返回yield后面(右边)的值。重点是: 下一 - 次迭代时,从上一 - 次迭代遇到的yield后面的代码(下一 - 行)开始执行
            # 简要理解: yield就是return返回 - -个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始
            #获取一个book就将book交给pipelines
            yield boook

items.py

class ScrapyDangdangItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    #通俗的说就是你要下载的数据都有什么
    #图片
    src=scrapy.Field()
    #名字
    name=scrapy.Field()
    #价格
    price=scrapy.Field()
    #作者
    author=scrapy.Field()

4.翻页

第一页 http://category.dangdang.com/cp01.01.03.41.00.00.html

第二页 http://category.dangdang.com/pg2-cp01.03.41.00.00.00.html

第三页 http://category.dangdang.com/pg3-cp01.03.41.00.00.00.html

第四页 http://category.dangdang.com/pg4-cp01.03.41.00.00.00.html

所以总结:

http://category.dangdang.com/pg{}-'-cp01.03.41.00.00.00.html'

        if self.page<10:#就不保存完了
            self.page=self.page+1
            url=self.base_url+str(self.page)+'-cp01.03.41.00.00.00.html'
            print('+++++++++++++++++第{}页++++++++++++++++++'.format(self.page))
            yield scrapy.Request(url=url,callback=self.parse)

5.保存至本地

    def open_spider(self,spider):
        print('+'*50)
        self.fp=open('book.json','w',encoding='utf-8')
    #items就是yield后面的book对象
    def process_item(self, item, spider):
        #以下这种模式不推荐,因为没传递过来一个对象,那么就打开一次文件,对文件操作过于频繁
        # #(1)write方法必须要写一个字符串,而不能是其他的对象
        # #(2)w模式 会每一个对象都打开一次文件   覆盖之前的内容     因此改成a
        # with open('book1.json','a',encoding='utf-8') as fp:
        #     fp.write(str(item))
        self.fp.write(str(item))
        return item

    # 在爬虫文件执行之后,才执行的方法
    def close_spider(self,spider):
        print('-'*50)
        self.fp.close()

6.将图片下载至本地books文件夹中

    def process_item(self, item, spider):
        # url = 'http:' + item.get('src')
        url = item.get('src')
        filename = './books/' + item.get('name') + '.jpg'
        if not os.path.exists('./books/'):
            os.makedirs('./books/')
        try:
            urllib.request.urlretrieve(url=url, filename=filename)
        except urllib.error.URLError as e:
            print(f"Failed to retrieve {url}: {e.reason}")
        return item

7.运行

from scrapy import cmdline
cmdline.execute(['scrapy','crawl','dang','--nolog'])

运行结果:


http://www.kler.cn/news/364208.html

相关文章:

  • JS | 如何使用 JavaScript 实现图片懒加载的淡入效果?
  • 在合规的地方怎么用EACO地球链兑换交换价值?
  • 基于Ubuntu24.04,下载并编译Android12系统源码 (二)
  • Linux的目录结构 常用基础命令(2)
  • 电子设备老化实验怎么做?
  • Linux运维篇-ansible的使用
  • C++音视频03:媒体信息打印、提取音视频、转封装、剪辑
  • Django+Vue项目搭建
  • windows DLL技术-DLL的调用和数据范围
  • 8.2024.10.24
  • Ubuntu忘记密码
  • 基于Python+SQL Server2008实现(GUI)快递管理系统
  • CSS的外边距合并规则
  • C++学习笔记----9、发现继承的技巧(五)---- 多重继承(2)
  • 技术成神之路:二十三种设计模式(导航页)
  • linux中time_wait过多问题怎么解决
  • 部署前后端分离若依项目--CentOS7Docker版
  • Qt Splash 与登录界面窗口
  • 【Bug】RuntimeError: Engine loop has died
  • 网站安全问题都有哪些,分别详细说明
  • Flutter通过showDialog实现下拉筛选菜单效果
  • Konva 组,层级
  • Altera宣布价格上调,最高上调20%
  • 微知-Linux内核自带的模块被压缩为ko.xz后如何恢复成不压缩版本?(xz -d xxx.ko.xz)
  • React-Route新版本(v6或以上)用法示例
  • centos7源码编译qt5.15.15