Scrapy爬虫框架实战

news2024/10/7 2:20:05

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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vite+React+Electron开发入门,10分钟搭建本地环境并打包

前言 想使用vite和react开发跨平台桌面的软件方案有electron和tauri两种&#xff0c;但是我个人更喜欢tauri&#xff0c;无奈electron名声大燥&#xff0c;面试要求里很多都写着&#xff1a;electron...可见这类公司多么落后。但是呢&#xff0c;又秉持着存在即合理的理念&…

Android 12 源码分析 —— 应用层 五(SystemUI的StatusBar类的启动过程和三个窗口的创建)

Android 12 源码分析 —— 应用层 五&#xff08;SystemUI的StatusBar类的启动过程和三个窗口的创建&#xff09; 在前面的文章中&#xff0c;我们介绍了SystemUI App的基本布局和基本概念。接下来&#xff0c;我们进入SystemUI应用的各个UI是如何被加入屏幕的。那么我们就先从…

计算机视觉实战项目(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别)

图像分类 教程博客_传送门链接:链接 在本教程中&#xff0c;您将学习如何使用迁移学习训练卷积神经网络以进行图像分类。您可以在 cs231n 上阅读有关迁移学习的更多信息。 本文主要目的是教会你如何自己搭建分类模型&#xff0c;耐心看完&#xff0c;相信会有很大收获。废话不…

Linux——Shell脚本编程(1)

一、为什么要学习 Shell 编程 &#xff1f; 1)Linux运维工程师在进行服务器集群管理时&#xff0c;需要编写Shell程序来进行服务器管理。 2)对于 JavaEE 和 Python 程序员来说&#xff0c;工作的需要&#xff0c;要求你编写一些 Shell脚本进行程序或者是服务器的维护&#xff…

【Linux学习笔记】基础命令2

1. rmdir指令 && rm指令1.1. 基础概念1.2. 命令用法1.2.1. rmdir命令1.2.2. rm命令1.2.3. rm命令的注意事项 2. man命令3. cp指令3.1. cp指令基础概念3.2. cp命令的用法 4. mv命令5. cat命令6. more命令 && less命令6.1. more命令6.2. less命令 7. head命令和t…

C#下使用IronPython来实现热更新

问题 之前我们学习过Roslyn&#xff0c;他可以动态编译代码并运行&#xff0c;然后通过ALC加载即插即用&#xff0c;但是遇到一些问题感觉无法解决&#xff0c;我编写一个类A在ALC中&#xff0c;另外一个类B要实例化这个A&#xff0c;我想让他们都能灵活卸载&#xff0c;但是如…

MySQL与ES数据同步的四种方案及实践演示

文章目录 一、同步双写优点缺点双写失败风险项目演示 二、异步双写&#xff08;MQ方式&#xff09;优点缺点项目演示 三、基于Datax同步核心组件架构图支持的数据源及操作项目演示 四、基于Binlog实时同步实现原理优点缺点项目演示 一、同步双写 也就是同步调用&#xff0c;这…

IPIDEA动态代理IP更适合于哪些业务场景?为什么动态代理IP更经济实惠?

动态代理IP是一种非常有用的工具&#xff0c;在许多业务场景中发挥重要作用。动态代理IP可以帮助用户提高网络速度和稳定性&#xff0c;提高工作效率&#xff0c;对于需要进行跨境业务的企业和个人来说尤为重要。 让我们先来看看动态代理IP更适合于哪些业务场景。 1.数据采集…

StraUML的详细使用步骤

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于JRebel & XRebel的相关操作吧 下载和安装&#xff1a;首先&#xff0c;你需要从StarUML的官方网站或适用于你操作系统的应用商店下载并安装StarUML软件Sta…

人工智能:神经细胞模型到神经网络模型

人工智能领域中的重要流派之一是&#xff1a;从神经细胞模型&#xff08;Neural Cell Model&#xff09;到神经网络模型&#xff08;Neural Network Model&#xff09;。 一、神经细胞模型 第一个人工神经细胞模型是“MP”模型&#xff0c;它是由麦卡洛克、匹茨合作&#xff0…

基于spingboot的websocket订阅、广播、多人聊天室示例

概述 基于spingboot的websocket多人聊天系统。包括订阅&#xff0c;广播、点对点单人聊天&#xff0c;多人聊天室功能。 详细 一、运行效果 简单示例 广播 单人聊天 多人聊天室 二、相关代码 websocket配置 package com.iamgpj.demowebsocket.config;import com.iamgpj.d…

更大的数据库,更多的分析内容!凌恩明星产品鱼类eDNA产品再次大升级!!

喜大普奔&#xff0c;凌恩生物明星产品鱼类eDNA产品再次大升级&#xff01;自建鱼类数据库&#xff0c;本次升级获得了更大的数据库&#xff0c;更全面的物种分类&#xff0c;更多的分析内容&#xff0c;鱼类物种检测更加精准&#xff01;&#xff01; eDNA宏条形码技术在鱼类…

移植FlashDB、SFUD到STM32f407

个人上篇文章 搭建STM32F407的SPI-Flash&#xff08;基于STM32CubeMX&#xff09;_小刚学長的博客-CSDN博客 主要是解决STM32CubeMX这边的配置&#xff0c;对code端侧是简单介绍了下 实际项目上一般都是拿片外flash存储一些东西&#xff0c;比如一些比较多的配置、参数&…

stu01-IDEA怎么创建一个HTML项目

1.打开idea&#xff0c;依次点击file→new→project 2.点击Java&#xff0c;选择你的jdk&#xff0c;没有下载的点击“Download JDK”/已经下载有JDK但在这里没显示的→点击“Add JDK”&#xff0c;选择你安装的JDK的路径&#xff0c;然后next 3.next 4.起好名字&#xff0c;我…

Python之OS模块

os模块负责程序与操作系统的交互&#xff0c;提供了访问操作系统底层的接口;即os模块提供了非常丰富的方法用来处理文件和目录。 使用的时候需要导入该模块:import os

【数据结构】树的基础知识及三种存储结构

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

定时任务执行脚本

1、编写bat脚本 将newman运行测试集的命令编写为bat脚本保存 2、设置定时任务 在计算机上右键->管理&#xff0c;在弹出菜单里的任务计划程序里创建定时任务配置执行

MySQL 8.0 驱动与阿里druid版本兼容操作

注意&#xff1a;这个异常表面druid数据源的版本与MySql 8.0的驱动版本不匹配&#xff0c;解决方法如下&#xff1a; 确保MySql 8.0的驱动如下网址&#xff1a; <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifact…

c语言练习题52:写一个函数判断当前机器是大端还是小端

代码&#xff1a; #include<stdio.h> int check_sys() {int a 1;return *(char*)&a;//小端retrun 1 大端return 0&#xff1b; } int main() {if (check_sys() 1) {printf("小端\n");}elseprintf("大端\n"); } 这里首先取a的地址&#xff0c…

腾讯云服务器怎么样?详细说下站长的看法

购买云服务器首选腾讯云&#xff0c;腾讯云服务器怎么样&#xff1f;作为国内头部原厂商的腾讯云&#xff0c;云服务器无论从安全性、可靠性和速度方面都有很好的保证&#xff0c;腾讯云服务器网来详细说下腾讯云服务器的优势以及腾讯云服务器购买流程&#xff1a; 目录 腾讯…