python scrapy 使用教程

python scrapy 使用教程

Scrapy介绍

Scrapy 是一个应用程序框架,用于抓取网站和提取结构化数据,这些数据可用于广泛的有用应用程序,如数据挖掘、信息处理或历史存档。
Scrapy爬虫框架的优点主要有以下几点:

  • 便于提取数据:内置支持 selecting and extracting 使用扩展的CSS选择器和XPath表达式从HTML/XML源中获取数据,并使用正则表达式提取助手方法。
  • 便于获取数据的持久化:内置支持 generating feed exports 以多种格式(json、csv、xml)存储在多个后端(ftp、s3、本地文件系统),以及可以通过自定义中间间将获取的数据保存在数据库。
  • 便于扩展和自定义:Scrapy本身内置了很多用于处理爬虫过程中的中间件:
    cookie和会话处理
    HTTP功能,如压缩、身份验证、缓存
    用户代理欺骗
    robots.txt
    爬行深度限制
    等等,并支持构建属于自己的中间件,满足不同的业务需求。
  • 支持高并发:Scrapy高并发的实现是基于Twisted库实现的并发。Twisted是一个基于事件驱动的Python网络框架,它使用非阻塞的I/O模型,能够处理大量并发连接,从而实现高性能的网络应用。Scrapy利用Twisted库的异步网络引擎,可以同时发送多个请求并处理多个响应,实现了高效的并发处理能力。但是过高的并发会给爬取的网站带来很大的压力。

Scrapy 安装

支持的Python版本

Scrapy需要python3.6+,CPython实现(默认)或pypy7.2.0+实现

安装 Scapy

如果用 Anaconda 或 Miniconda ,您可以从 conda-forge 频道,它有针对Linux、Windows和macOS的最新软件包。

使用 conda 安装Scrapy 运行:
conda install -c conda-forge scrapy

使用pip 安装:
pip install Scrapy

Scrapy 依赖包

Scrapy 是用纯python编写的,它依赖于几个关键的python包(以及其他包):

  • lxml 一个高效的XML和HTML解析器
  • parsel ,一个写在lxml上面的html/xml数据提取库
  • w3lib ,用于处理URL和网页编码的多用途帮助程序
  • twisted 异步网络框架
  • cryptographypyOpenSSL ,处理各种网络级安全需求

以上包不需要手动安装,安装Sccrapy的时候会自动安装,了解即可。

Scrapy构成及运行原理

了解Scrapy的构成和运行原理是很有必要的,有助于在使用scrapy的过程中解决遇到的各种问题,只有知其所以然,用起来才能得心应手。

Scrapy架构

以下是scrapy架构图:
scrapy架构图
通过架构图得知Scrapy是由以下几个部分组成的。

  • Scrapy engine (引擎):引擎就像爬虫的大脑,控制整个爬取过程的核心,负责调度和协调其他组件的工作。
  • Scheduler (调度器):调度器负责接收引擎传递过来的请求,将其放入队列中,并在引擎请求时返回。正是因为调度器在队列中处理请求,才能够实现并发爬虫。
  • Downloader (下载器):负责下载引擎传递的请求,并将下载好的响应返回给引擎。
  • Middleware (中间件):处理引擎和下载器之间的请求和响应,可以用来进行请求的过滤、响应的处理等操作。
  • Spiders (爬虫):在spiders中编写我们的爬虫代码,主要的爬取逻辑在这里实现。
  • Item、Pipline (项和管道) :在item中定义我们要获取数据的结构,在pipline中用于进一步处理提取的数据等,使得爬取过程更加简单和高效。

Scrapy 如何运转

现在我们知道了Scrapy的组成,那么它是如何运转的呢,运转的大致流程如下:

  1. 当启动我们的Scrapy爬虫时,引擎首先从 Spider 中获取初始请求。
  2. 然后引擎将获取到的请求发送给调度器进行处理。
  3. 调度器将请求排队并通过下载器中间件发送给下载器。
  4. 下载器将下载的响应返回给引擎。
  5. 然后引擎将响应发送给蜘蛛进行解析并生成新的请求。

如果在以上流程中设置了蜘蛛中间件,就可以在蜘蛛处理请求和生成响应的过程中进行干预。它可以用来处理请求和响应、添加新的请求、修改 Item 对象等。
如果设置了下载器中间件,就可以在下载请求和处理响应的过程中进行干预。它可以用来修改请求和响应、处理异常、设置代理等。
tips:
这个过程循环执行,直到没有新的请求可以发送为止。最后,蜘蛛将处理完的数据通过管道组件进行处理和存储。

构建Scrapy项目

在开始抓取之前,我们必须建立一个新的项目。通过命令行输入要在其中存储代码并运行的目录:

scrapy startproject scrapy_project

scrapy_project是我们创建的项目名,scrapy将创建一个 scrapy_project 目录包含以下内容

scrapy_project/
    scrapy.cfg            # scrapy配置文件

    scrapy_project/             # scrapy_projec包
        __init__.py

        items.py          # 定义spider数据结构的文件

        middlewares.py    # 项目中间件文件

        pipelines.py      # 项目管道文件

        settings.py       # 项目设置文件

        spiders/          # 爬虫文件夹
            __init__.py

开始编写Spider

在spiders文件夹下新建一个py文件,在文件中定义一个爬虫类,这个类必须继承自 scrapy.Spider 并设置一个名为 name 的类变量为我们的爬虫名:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')

可以看到在QuotesSpider类中定义了一些属性和方法:

  • name :标识蜘蛛。它在一个项目中必须是唯一的,即不能为不同的爬行器设置相同的名称。
  • start_requests() :必须返回请求的可迭代(您可以返回请求列表或编写生成器函数),爬行器将从该请求开始爬行。后续请求将从这些初始请求中相继生成。
  • parse() :将被调用以处理为每个请求下载的响应的方法。Response参数是 TextResponse 它保存页面内容,并具有进一步有用的方法来处理它。
    这个 parse() 方法通常解析响应,将抓取的数据提取为字典,还查找要遵循的新URL并创建新请求 (Request )。

启动爬虫

首先进入到项目根目录,在命令行中输入以下命令来启动爬虫:

scrapy crawl quotes

此命令将会启动我们的Spider,并向quotes.toscrape.com这个网站发起请求,并将获取到的html页面保存在文件中。
此时控制台会打印类似以下字符:

... (omitted for brevity)
2024-01-01 21:24:05 [scrapy.core.engine] INFO: Spider opened
2024-01-01 21:24:05 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2024-01-01 21:24:05 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2024-01-01 21:24:05 [scrapy.core.engine] DEBUG: Crawled (404) <GET http://quotes.toscrape.com/robots.txt> (referer: None)
2024-01-01 21:24:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
2024-01-01 21:24:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/2/> (referer: None)
2024-01-01 21:24:05 [quotes] DEBUG: Saved file quotes-1.html
2024-01-01 21:24:05 [quotes] DEBUG: Saved file quotes-2.html
2024-01-01 21:24:05 [scrapy.core.engine] INFO: Closing spider (finished)
...

引擎做了什么

首先运行start_requests方法,yield scrapy.Request 方法返回的 Request 对象 。在接收到每个请求的响应后,它会实例化 Response 对象,并调用与请求关联的回调方法(在本例中, parse 方法)将响应作为参数传递。
这里的RequestResponse 对象是Scrapy框架封装的对象,与requests库的使用方法有区别。

启动请求方法的快捷方式

可以不实现 start_requests() 方法,该方法生成 scrapy.Request 对象,可以只定义一个 start_urls 具有URL列表的类属性。然后,此列表将由的默认实现使用 start_requests() 要为爬行器创建初始请求:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)

这个 parse() 方法来处理这些URL的每个请求,即使我们还没有显式地告诉Scrapy这样做。发生这种情况是因为 parse() 是Scrapy的默认回调方法,在没有显式分配回调的情况下为请求调用该方法。
这种方法作为了解即可,一般不会用到

提取数据

Scrapy 提供了非常方便的 Scrapy Shell 供我们在解析数据的时候方便我们调试提取数据的方法,在Scrapy Shell中支持xpath和css解析,非常的方便。
只需要在命令行中输入:

scrapy shell “http://quotes.toscrape.com/page/1/”

Shell将会输出以下类似内容:

[ ... Scrapy log here ... ]
2024-01-01 12:09:27 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x7fa91d888c90>
[s]   item       {}
[s]   request    <GET http://quotes.toscrape.com/page/1/>
[s]   response   <200 http://quotes.toscrape.com/page/1/>
[s]   settings   <scrapy.settings.Settings object at 0x7fa91d888c10>
[s]   spider     <DefaultSpider 'default' at 0x7fa91c8af990>
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   fetch(req_or_url) Fetch request (or URL) and update local objects
[s]   view(response)    View response in a browser

我个人建议在提取数据的时候使用Xpath选择器,因为XPath表达式是非常强大的,是抓取选择器的基础。实际上,CSS选择器在引擎盖下转换为xpath。虽然不如css选择器那么流行。

未完待续。。。

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值