Scrapy爬虫框架实战

2023-09-12 22:53:22

Python实现爬虫是很容易的,一般来说就是获取目标网站的页面,对目标页面的分析、解析、识别,提取有用的信息,然后该入库的入库,该下载的下载。以前写过一篇文章《Python爬虫获取电子书资源实战》,以一个电子书的网站为例来实现python爬虫获取电子书资源。爬取整站的电子书资源,按目录保存到本地,并形成索引文件方便查找。这次介绍通过Scrapy爬虫框架来实现同样的功能。

一、Scrapy简介

Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架。
Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
通常我们可以很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片。
Scrapy爬虫框架

  • Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。
  • Scheduler(调度器):它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
  • Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
  • Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器).
  • Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方。
  • Downloader Middlewares(下载中间件):可以当作是一个可以自定义扩展下载功能的组件。
  • Spider Middlewares(Spider中间件):可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)

二、Scrapy实战

虽然用python写一个爬虫也不是很费事,但是有了Scrapy以后让你实现爬虫更简单,更加通用,现在我们还是以《Python爬虫获取电子书资源实战》中的例子,爬取目标网站kgbook.com。也可以对比看一下通过Scrapy爬虫框架实现相同的功能有多么的方便。

1、Scrapy安装

首先通过 pip 安装 Scrapy 框架

pip install Scrapy

2、创建Scrapy项目工程

创建getbooks的项目

scrapy startproject getbooks

创建一个getkgbook的爬虫,目标网站kgbook.com

scrapy genspider getkgbook kgbook.com

项目的结构如下图所示
Scrapy项目目录结构

3、实现Scrapy的爬虫代码

爬数据

主要的爬虫逻辑实现代码都在getkgbook.py中,在这里实现目录的爬取、翻页、进入到详情页,并解析详情页的数据。
getkgbook.py

import os
import re
import scrapy
from getbooks.items import KgbookItem


class GetkgbookSpider(scrapy.Spider):
    name = "getkgbook"  #爬虫的名称
    allowed_domains = ["kgbook.com"]   #爬取的网站
    start_urls = ["https://kgbook.com"]  #爬取的首页

    def parse(self, response):
        categorys = response.xpath('//div[@id="category"]/div/ul/li/a')
        for category in categorys:
            category_url = category.xpath('./@href').extract_first()
            url=response.urljoin(category_url)
            #爬取进入到目录页
            yield response.follow(url, self.parse_booklist) 

    #解析目录页
    def parse_booklist(self,response):
        book_list_select=response.css('.channel-item h3.list-title a')
        #获取书籍列表
        for book_info_select in book_list_select:
            book_name=book_info_select.css('::text').extract_first()
            book_detail_url=book_info_select.css('::attr(href)').extract_first()
            book_detail_url=response.urljoin(book_detail_url)
            print(book_name,book_detail_url)
            yield scrapy.Request(url=book_detail_url, callback=self.pase_bookdetail)
        #翻页
        nextpage_url = response.xpath('//div[@class="pagenavi"]/a[contains(text(), "下一页")]/@href').extract_first()
        if nextpage_url:
            yield response.follow(nextpage_url, self.parse_booklist)

    #解析详情页
    def pase_bookdetail(self,response):
        navegate=response.xpath('//nav[@id="location"]/a')
        if len(navegate)>1:
            book_category=navegate[1].xpath('./text()').extract_first()
        book_name=response.css('.news_title::text').extract_first()
        book_author=response.xpath('//div[@id="news_details"]/ul/li[contains(text(),"作者")]/text()').extract_first()
        pattern=re.compile('mobi|epub|azw3|pdf',re.I) #解析书籍的类型
        book_download_urls=response.xpath('//div[@id="introduction"]/a[@class="button"]')
        for book_download_urlinfo in book_download_urls:
            book_type=book_download_urlinfo.re(pattern)
            if book_type:
                book_download_url=book_download_urlinfo.xpath('./@href').extract_first()
                #获取要下载的书籍的名称、作者、要保存的路径、下载地址
                item=KgbookItem()
                item['book_name']=book_name
                item['book_author']=book_author
                item['book_file']=os.path.join(book_category,book_name+"."+str(book_type[0]).lower())
                item['book_url']=book_download_url
                print(book_name,book_author,book_download_url,item['book_file'])
                return item

在这里我们通过xpath解析器和css解析器来解析获取网页中的有用的信息。如提取a 标签的href的信息 ,提取书籍的名称、作者、下载链接等信息。

保存数据

item.py
在item.py中定义了KgbookItem类,Item 定义结构化数据字段,用来保存爬取到的数据,有点像 Python 中的 dict,但是提供了一些额外的保护减少错误。在这里定义了book_name、book_author、book_file、book_url这些信息都会通过爬虫提取后保存用来输出到文件或数据库等。

import scrapy

class KgbookItem(scrapy.Item):
    book_name=scrapy.Field()
    book_author=scrapy.Field()
    book_file=scrapy.Field()
    book_url=scrapy.Field()
下载数据

通过pipelines定义文件下载的管道类
pipelines.py

from scrapy import item, Request
from scrapy.pipelines.files import FilesPipeline

class KgBookFilePipeline(FilesPipeline):

    def get_media_requests(self,item,info):
        yield Request(item['book_url'],meta={'book_file':item['book_file']})

    def file_path(self, request, response=None, info=None):
        file_name=request.meta.get('book_file')
        return file_name

这里实际上只做两件事,一是get_media_requests下载文件,二是组织文件要保存的路径。会通过相应的下载中间件将文件下载并保存在需要保存的目录。这里我们规划的保存目录是书籍目录\书名.类型。
还需要在settings.py中定义下载后保存的路径

# 保存书籍的路径
FILES_STORE='./books'
定义自定义下载的管道
ITEM_PIPELINES = {
   "getbooks.pipelines.KgBookFilePipeline": 300,
}

加入以下定义,强制爬取、下载,并忽略301,302重定向

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

MEDIA_ALLOW_REDIRECTS = True

HTTPERROR_ALLOWED_CODES = [301,302]

至此,就通过Scrapy爬虫框架实现了一个爬虫。
运行效果
执行 scrapy crawl getkgbook -o books.json
可以看到控制台打印出来的日志,爬虫开始默默的勤勤恳恳的爬取了。
爬取日志

爬取的结果保存到了books.json中
books.json

要下载的书籍也保存到了books下相应的目录下了
保存的文件

三、注意事项

有可能在文件下载的时候并没有把文件下载下来,原因是文件下载路径有重定向。

2023-09-12 22:25:38 [scrapy.core.engine] DEBUG: Crawled (301) <GET https://kgbook.com/e/DownSys/GetDown?classid=24&id=471&pathid=0> (referer: None)
2023-09-12 22:25:38 [scrapy.pipelines.files] WARNING: File (code: 301): Error downloading file from <GET https://kgbook.com/e/DownSys/GetDown?classid=24&id=471&pathid=0> referred in <None>
2023-09-12 22:25:38 [scrapy.core.engine] DEBUG: Crawled (301) <GET https://kgbook.com/e/DownSys/GetDown?classid=24&id=4742&pathid=0> (referer: None)
2023-09-12 22:25:38 [scrapy.pipelines.files] WARNING: File (code: 301): Error downloading file from <GET https://kgbook.com/e/DownSys/GetDown?classid=24&id=4742&pathid=0> referred in <None>

需要在settings.py中加入

MEDIA_ALLOW_REDIRECTS = True  #直接下载

HTTPERROR_ALLOWED_CODES = [301,302]  #忽略重定向的报错信息

现在我们通过一个Scrapy爬虫框架实例实现了网站的爬取,重代码量上看比python直接写少了很多,通用性也更强了。通过管道不仅仅可以将数据保持至json还可以保存到Excel、数据库等。


博客地址:http://xiejava.ishareread.com/

更多推荐

19 Python的math模块

概述在上一节,我们介绍了Python的sys模块,包括:sys模块中一些常用的属性和函数。在这一节,我们将介绍Python的math模块。math模块提供了许多数学函数和常量,可以用于进行各种数学运算和常数表示。math模块中的常量和函数主要分为以下几类:常量:包括math.pi、math.e等,用于表示圆周率π和自然

php函数usort使用方法

在PHP中,usort()函数用于对数组进行排序,它允许你使用自定义的比较函数来确定元素的顺序。以下是usort()函数的使用方法:usort(array&$array,callable$cmp_function):bool参数说明:$array:要排序的数组,是传入函数的引用。$cmp_function:自定义的比较

BiLSTM(双向LSTM)实现股票时间序列预测(TensorFlow2版)

本专栏旨在通过实战案例帮助深度学习初学者通过实战案例快速掌握深度学习的核心概念和技术,这个专栏将覆盖以下关键主题:深度学习基础:介绍深度学习的基本原理以及数学概念,你将了解到神经网络的工作原理、激活函数、优化算法等基本概念。常见算法:例如卷积神经网络(CNN)、循环神经网络(RNN)和生成对抗网络(GAN)。数据预处理

SQL server中字段自增:IDENTITY、序列Sequence

SQLserver中字段自增:IDENTITY、序列Sequence1.列字段自增`IDENTITY在SQLServer中,IDENTITY(1,1)是用于定义一个自增长列的属性。它的含义如下:IDENTITY:表示该列是一个自增长列。(1,1):表示自增长列的起始值为1,每次递增1。当你在创建表时使用IDENTITY

Sqlserver 监控使用磁盘空间情况

最近遇到一个小问题:为了保存以往的一些数据,间了大量临时表,导致SQLserver数据增长过快,不得不想个办法监控磁盘空间使用情况。网上一般有几种办法:一是使用dm_os_volume_stats函数,缺点是无法获取非数据库所在的磁盘空间使用情况。二是使用Execmaster.dbo.xp_fixeddrives,缺点

算法基础:图

图论图论〔GraphTheory〕是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。如下就是一种逻辑上的图结构:图是一种最复杂的数据结构,前面讲的数据结构都可以看成是图的特

oracle 12c相对oralce 11g的新特性(3)|oracle 12c的自动化管理特性:自动备份、自动恢复、自动维护的功能使用

一、前言:前面几期讲解了oracle12c多租户的使用、In-Memory列存储来提高查询性能以及数据库的克隆、全局数据字典和共享数据库资源的使用今天我们讲讲oracle12c的另外的一个自动化管理功能新特性:自动备份、自动恢复、自动维护的功能二、自动备份、自动恢复、自动维护概要通过使用这些自动化功能,Oracle12

使用 FHE 实现加密大语言模型

近来,大语言模型(LLM)已被证明是提高编程、内容生成、文本分析、网络搜索及远程学习等诸多领域生产力的可靠工具。大语言模型对用户隐私的影响尽管LLM很有吸引力,但如何保护好输入给这些模型的用户查询中的隐私这一问题仍然存在。一方面,我们想充分利用LLM的力量,但另一方面,存在向LLM服务提供商泄露敏感信息的风险。在某些领

PCIE研究-1

PCI-Express(peripheralcomponentinterconnectexpress)是一种高速串行计算机扩展总线标准,PCIe属于高速串行点对点双通道高带宽传输,所连接的设备分配独享通道带宽,不共享总线带宽,主要支持主动电源管理,错误报告,端对端的可靠性传输,热插拔以及服务质量(QOS)等功能。PCI

【大数据实训】基于Hadoop的2019年11月至2020年2月宁波天气数据分析(五)

博主介绍:✌全网粉丝6W+,csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于大数据技术领域和毕业项目实战✌🍅文末获取项目联系🍅基于Hadoop的2019年11月至2020年2月宁波天气数据分析2019—2020学年第二学期《分布式系统原理与技术》期

如何使用Java爬取指定链接的网页内容

在当今信息时代,互联网上的数据量庞大且不断增长。为了获取特定网页的内容,爬虫技术成为了一种非常有用的工具。本文将介绍如何使用Java编程语言来实现爬取指定链接的网页内容。首先,我们需要准备好Java开发环境。确保你已经安装了JavaDevelopmentKit(JDK)并配置好了环境变量。接下来,我们将使用Java提供

热文推荐