Scrapy爬虫框架实战

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 KgbookItemclass 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_nameitem['book_author']=book_authoritem['book_file']=os.path.join(book_category,book_name+"."+str(book_type[0]).lower())item['book_url']=book_download_urlprint(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 scrapyclass 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 FilesPipelineclass 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 = FalseMEDIA_ALLOW_REDIRECTS = TrueHTTPERROR_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.hqwc.cn/news/107521.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【VS插件】VS code上的Remote - SSH

【VS插件】VS code上的Remote - SSH 目录 【VS插件】VS code上的Remote - SSH获得Linux服务器或者Linux系统的IP地址下载插件远程登录注意如果Linux虚拟机系统无法连接成功可能是没有开启ssh服务优势 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2023.9.12 前言&#xff1…

c#动态保留小数位数的数值格式化方法实例----从小数点后非零数字保留两位进行四舍五入

c#动态保留小数位数的数值格式化方法实例----从小数点后非零数字保留两位进行四舍五入 功能介绍代码案例输出结果封装扩展方法控制台调用 其他方法地址 功能介绍 1. 输入的数字是整数&#xff0c;则直接返回整数部分的字符串表示。 2. 如果输入的数字是小数&#xff0c;则执行…

antd react 文件上传只允许上传一个文件且上传后隐藏上传按钮

antd react 文件上传只允许上传一个文件且上传后隐藏上传按钮 效果图代码解析 效果图 代码解析 import { Form, Upload, message } from antd; import { PlusOutlined } from ant-design/icons; import { useState, useEffect } from react; import { BASE_URL } from /utils/…

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

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

【实践篇】redis管道pipeline使用详解

文章目录 0. 前言什么场景下使用redis管道特性 1.原理1.1 redis管道特性的处理机制 使用redis管道优化示例3. springboot使用redis管道示例4. 参考资料5. 源码地址6. Redis从入门到精通系列文章 0. 前言 Redis管道&#xff08;Pipeline&#xff09;是一种批量执行Redis命令的机…

php版 短信跳转微信小程序

实现这功能首先&#xff0c;小程序端添加业务域名 php代码 <?php declare (strict_types1);namespace app\controller\Admin;use app\model\Set; use app\Request;class Admin_Url_Scheme {public function getScheme(Request $request) {$appid 小程序appid;$secret 小…

卫星物联网生态建设全面加速,如何抓住机遇?

当前&#xff0c;卫星通信无疑是行业最热门的话题之一。近期发布的华为Mate 60 Pro“向上捅破天”技术再次升级&#xff0c;成为全球首款支持卫星通话的大众智能手机&#xff0c;支持拨打和接听卫星电话&#xff0c;还可自由编辑卫星消息。 据悉&#xff0c;华为手机的卫星通话…

webrtc-m79-测试peerconnectionserver的webclient-p2p-demo

1 背景 webrtc的代码中有peerconnectionclient和peerconnectionserver的例子&#xff0c;但是没有对应的web端的例子&#xff0c;这里简单的写了一个测试例子&#xff0c;具体如下&#xff1a; 2 具体操作 2.1 操作流程 2.2 测试效果 使用webclient与peerconnectionclient的…

【SpringMVC】JSR303与拦截器的使用

文章目录 一、JSR3031.1 JSR303是什么1.2 JSR 303的好处包括1.3 常用注解1.4 实例1.4.1 导入JSR303依赖1.4.2 规则配置1.4.3 编写校验方法1.4.4 编写前端 二、拦截器2.1 拦截器是什么2.2 拦截器与过滤器的区别2.3.应用场景2.4 快速入门2.5.拦截器链2.6 登录拦截权限案例2.6.1 L…

【Spring面试】八、事务相关

文章目录 Q1、事务的四大特性是什么&#xff1f;Q2、Spring支持的事务管理类型有哪些&#xff1f;Spring事务实现方式有哪些&#xff1f;Q3、说一下Spring的事务传播行为Q4、说一下Spring的事务隔离Q5、Spring事务的实现原理Q6、Spring事务传播行为的实现原理是什么&#xff1f…

数据在内存中的存储(1)

目录 1、整数在内存中的存储 原码、反码、补码&#xff1a; 2、大小端&#xff1a; 前提须知&#xff1a; 大小端存储方式&#xff1a; 字节的顺序&#xff1a; 概念&#xff1a; 判断机器是大端还是小端&#xff1a; 代码展示&#xff1a; 代码优化1.0&#xff1a; …

linux————ansible

一、认识自动化运维 自动化运维: 将日常IT运维中大量的重复性工作&#xff0c;小到简单的日常检查、配置变更和软件安装&#xff0c;大到整个变更流程的组织调度&#xff0c;由过去的手工执行转为自动化操作&#xff0c;从而减少乃至消除运维中的延迟&#xff0c;实现“零延时”…