09—小白学Python爬虫之Scrapy快速入门与实战

2024-05-12 10:58

本文主要是介绍09—小白学Python爬虫之Scrapy快速入门与实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

从本篇起,将学习一下Scrapy爬虫框架,以及如何通过该框架实现定向爬虫。Scrapy是一个非常优秀的框架,操作简单,扩展方便,是比较流行的爬虫解决方案。

初识

Scrapy是使用Python编写的Crawler Framework,简单轻巧,其使用Twisted异步库来处理网络通信,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求。

架构及组件

首先看一下Scrapy的整体架构图(绿线是数据流向),如下:
这里写图片描述
根据架构图介绍一下Scrapy中各大组件及其功能:
- Scrapy引擎(Engine):负责Spider ItemPipeline Downloader Scheduler之间的通讯、数据传递等
- 调度器(Scheduler):负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,加入队列,当引擎需要时,交还给引擎
- Downloader(下载器):负责下载引擎发送过来的所有Request请求,并将其获取到的Responses交还给引擎,由引擎交给Spider来处理
- Spider(爬虫):负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)
- ItemPipeline(管道):负责处理Spider中获取的Item,并进行后期处理,比如详细分析、过滤、存储等
- 下载器中间件(Downloader middlewares):是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的Response,可以自定义扩展下载功能
- Spider Middlewares(Spider中间件):是在引擎与Spider之间的特定钩子,可以自定义扩展通信功能,比如进入Spider的Responses和从Spider出去的Requests

Scrapy工作流程

官方版
  1. 引擎打开一个网站(open a domain),找到处理该网站的Spider,并向该Spider请求第一个要爬取的URL
  2. 引擎从Spider中获取到第一个要爬取的URL并通过调度器(Scheduler)以及Request进行调度
  3. 引擎向调度器请求下一个要爬取的URL
  4. 调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载中间件(请求request方向)转发给下载器(Downloader)
  5. 一旦页面下载完毕,下载器会生成该页面的Response,并将其通过下载中间件(返回response方向)发送给引擎
  6. 引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理
  7. Spider处理Response并返回爬取到的Item以及使用有需要跟进的新的Request给引擎
  8. 引擎将(Spider返回的)Item交给Item Pipeline,将(Spider返回的)Request给调度器
  9. (从第二步)重复直到调度器中没有Request,引擎关闭该网站
白话版
  1. 引擎:Hi!Spider, 你要处理哪一个网站?
  2. Spider:老大要我处理xxxx.com。
  3. 引擎:你把第一个需要处理的URL给我吧。
  4. Spider:给你,第一个URL是xxxxxxx.com。
  5. 引擎:Hi!调度器,我这有request请求你帮我排序入队一下。
  6. 调度器:好的,正在处理你等一下。
  7. 引擎:Hi!调度器,把你处理好的request请求给我。
  8. 调度器:给你,这是我处理好的request
  9. 引擎:Hi!下载器,你按照老大的下载中间件的设置帮我下载一下这个request请求
  10. 下载器:好的!给你,这是下载好的东西。(如果失败:sorry,这个request下载失败了。然后引擎告诉调度器,这个request下载失败了,你记录一下,我们待会儿再下载)
  11. 引擎:Hi!Spider,这是下载好的东西,并且已经按照老大的下载中间件处理过了,你自己处理一下(注意!这儿responses默认是交给def parse()这个函数处理的)
  12. Spider:(处理完毕数据之后对于需要跟进的URL),Hi!引擎,我这里有两个结果,这个是我需要跟进的URL,还有这个是我获取到的Item数据。
  13. 引擎:Hi !管道 我这儿有个item你帮我处理一下!调度器!这是需要跟进URL你帮我处理下。然后从第四步开始循环,直到获取完老大需要全部信息。
  14. 管道And调度器:好的,现在就做!

只有当调度器中不存在任何request了,整个程序才会停止。(也就是说,对于下载失败的URL,Scrapy也会重新下载。)

安装

Windows安装
  1. 安装pywin32,点我下载,下载响应版本的pywin32,双击安装即可。
  2. 安装pyOpenSSL,源码下载,下载完成后,运行python setup.py install安装即可
  3. 安装lxml,使用pip install lxml,如果提示Microsoft Visual C++库没安装,则需要下载响应支持的库,点我下载。
  4. 安装Scrapy,使用pip install Scrapy
Linux(macOS)

Linux下绝大部分版本都预装了Python环境,而且还预装了lxml和OpenSSL,所有直接使用pip install Scrapy安装即可。
接下来,会发现,安装了如下包:

Installing collected packages: six, w3lib, cssselect, parsel, pycparser, cffi, asn1crypto, cryptography, pyOpenSSL, PyDispatcher, zope.interface, constantly, incremental, attrs, Automat, hyperlink, Twisted, queuelib, pyasn1, pyasn1-modules, service-identity, Scrapy
Successfully installed Automat-0.6.0 PyDispatcher-2.0.5 Scrapy-1.5.0 Twisted-17.9.0 asn1crypto-0.24.0 attrs-17.4.0 cffi-1.11.5 constantly-15.1.0 cryptography-2.2.2 cssselect-1.0.3 hyperlink-18.0.0 incremental-17.5.0 parsel-1.4.0 pyOpenSSL-17.5.0 pyasn1-0.4.2 pyasn1-modules-0.2.1 pycparser-2.18 queuelib-1.5.0 service-identity-17.0.0 six-1.11.0 w3lib-1.19.0 zope.interface-4.4.3

点我查看官方各平台安装方法

入门实战

目标
  • 创建一个Scrapy项目
  • 定义提取的结构化数据(Item)
  • 编写爬取网站的Spider并提取结构化数据(Item)
  • 编写Item Pipelines存储提取到的Item
新建项目(scrapy startproject)
  • 在开始爬取之前,先创建新的Scrapy项目。进入目标项目目录后,执行以下命名:
scrapy startproject novelSpider
  • 其中novelSpider为项目名称,可以看到会在当前目录下创建novelSpider文件夹,目录结构如下:
    这里写图片描述
  • 简单介绍一下各文件作用:
    • scrapy.cfg:项目的配置文件
    • novelSpider/:项目的python模块,将会从这里引用代码
    • novelSpider/items.py:项目的目标文件
    • novelSoider/pipelines.py:项目的管道文件
    • novelSpider/settings.py:项目的设置文件
    • novelSpider/spiders:存储爬虫代码目录
明确目标(novelSpider/items.py)

在此,我们打算抓取http://www.jjwxc.net/topten.php?orderstr=13中小说的序号、作者、类型、进度等信息。

  1. 打开novelSpider目录下的items.py
  2. Item定义结构化数据字段,用来保存爬取到的数据,有点像Python中的dict,但提供了一些额外的保护减少错误
  3. 创建一个scrapy.Item类,并定义类型为scrapy.Field的类属性来定义一个Item
  4. 接下来,创建NovalItem类和构建item模型(model)
import scrapy
class NovelItem(scrapy.Item):id = scrapy.Field()author = scrapy.Field()title = scrapy.Field()type = scrapy.Field()style = scrapy.Field()process = scrapy.Field()date = scrapy.Field()
制作爬虫(spiders/novel.py)
爬数据

上一步在调用scrapy startproject novelSpider时,曾提示我们:

You can start your first spider with:cd novelSpiderscrapy genspider example example.com

接下来,就用到这个提示了。首先cd novelSpider进入小说爬虫目录,执行如下命令:

scrapy genspider novel "jjwxc.net"
  • 打开novelSpider/spiders目录中的novel.py,默认增加了如下代码:
# -*- coding: utf-8 -*-
import scrapyclass NovelSpider(scrapy.Spider):name = 'novel'allowed_domains = ['jjwxc.net']start_urls = ['http://jjwxc.net/']def parse(self, response):pass

其实我们也可以自行创建novel.py并编写上面代码,只不过使用命令可以免去编写固定代码的麻烦。

建立一个Spider,必须使用scrapy.Spider类创建一个子类,并确定三个属性和一个方法:

  1. name = "":爬虫的唯一标识,不可重复
  2. allowed_domains = []:爬虫搜索的域名范围,只能在该域名下进行爬取
  3. start_urls = []:爬取的URL元祖或列表。从这里开始抓取数据,也就是第一次下载的数据会从这些urls开始,其他子URL会从起始URL中继承性生成
  4. parse(self,response):解析方法,每个URL下载完成后被调用,传入Response对象作为参数,主要用来解析返回的网页数据(response.body),提取结构化数据(Item),生成下一页URL请求

在此,将start_urls的值修改为爬取的第一个url:

start_urls = ['http://www.jjwxc.net/topten.php?orderstr=13']
  • 修改parse方法
    def parse(self, response):filename = 'novel.html'with open(filename, 'w') as f:f.write(response.body.decode(response.encoding))
  • 运行抓取,执行如下命令
scrapy crawl novel

novel就是我们生成的唯一爬虫名。
运行之后,打印的日志出现[scrapy.core.engine] INFO: Spider closed (finished),代表执行完成。当前文件夹会出现一个novel.html文件,内容就是爬取网页的全部源代码信息。

取数据
  • 引入在novelSpider/items.py中定义的NovelItem
from novelSpider.items import NovelItem
  • 分析html内容,查询目标内容,把数据封装到NovelItem对象中
# -*- coding: utf-8 -*-
import scrapy
from novelSpider.items import NovelItemclass NovelSpider(scrapy.Spider):name = 'novel'allowed_domains = ['jjwxc.net']start_urls = ['http://www.jjwxc.net/topten.php?orderstr=13']def parse(self, response):content = response.body.decode(response.encoding)# filename = 'novel.html'# with open(filename, 'w') as f:#     f.write(content)# bgcolor #eefaeenovelList = []for item in response.xpath('//tr[@bgcolor="#eefaee"]'):id = item.xpath('td')[0].xpath('text()').extract()author = item.xpath('td')[1].xpath('a/text()').extract()title = item.xpath('td')[2].xpath('a/text()').extract()type = item.xpath('td')[3].xpath('text()').extract()style = item.xpath('td')[4].xpath('text()').extract()date = item.xpath('td')[8].xpath('text()').extract()# print(id, author, title, type, style, date)novelItem = NovelItem()novelItem['num'] = id[0]novelItem['author'] = author[0]novelItem['title'] = title[0]novelItem['type'] = type[0]novelItem['style'] = style[0]novelItem['date'] = date[0]novelList.append(novelItem)return novelList
  • 暂时先不处理管道,后面再详细介绍
保存数据

scray保存信息主要有四种,-o输出指定格式的文件,命令如下:

# json格式,默认为Unicode编码啊
scrapy crawl novel -o novels.json# json lines格式,默认为Unicode编码啊
scrapy crawl novel -o novels.jsonlines# json格式,默认为Unicode编码啊
scrapy crawl novel -o novels.json# xml格式
scrapy crawl novel -o novels.xml

好了,scrapy的基本介绍就到这了,有一个小问题,在parse方法中,我们使用的是return items,如果换成yield会有什么区别和不同呢?请听下回分解。

这篇关于09—小白学Python爬虫之Scrapy快速入门与实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/982437

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地