如何利用Scrapy爬取知名技术文章网站!干货真多!


Scrapy 是一个非常优秀的爬虫框架,通过 Scrapy 框架,可以非常轻松地实现强大的爬虫系统,我们只需要将精力放在抓取规则以及如何处理抓取的数据上即可,本文通过实战来介绍 Scrapy 的入门知识以及一些高级应用。

 

1. Scrapy 基础知识

1.1 Scrapy 简介

Scrapy 是适用于 Python 的一个快速、高层次的屏幕抓取和 web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy 用途广泛,可以用于数据挖掘、监测和自动化测试。Scrapy 主要是包括如下 6 个部分。

  1. Scrapy Engine (Scrapy引擎):用来处理整个系统的数据流,触发各种事件。
  2. Scheduler (调度器):从 URL 队列中取出一个 URL。
  3. Downloader (下载器):从 Internet 上下载 Web 资源。
  4. Spiders (网络爬虫):接收下载器下载的原始数据,做进一步的处理,例如,使用 Xpath 提取感兴趣的信息。
  5. Item Pipeline (项目管道):接收网络爬虫传过来的数据,以便做进一步处理。例如:存入数据库,存入文本文件。
  6. 中间件:整个 Scrapy 框架有很多中间件,如下载器中间件、网络爬虫中间件等,这些中间件相当于过滤器,夹在不同部分之间截获数据流,并进行特殊的加工处理。

以上各部分的工作流程可以使用下图所示的流程描述。


其流程可以描述如下:

  1. 爬虫中起始的 URL 构造成 Requests 对象 ⇒ 爬虫中间件 ⇒ 引擎 ⇒ 调度器
  2. 调度器把 Requests ⇒ 引擎 ⇒ 下载中间件 ⇒ 下载器
  3. 下载器发送请求,获取 Responses 响应 ⇒ 下载中间件 ⇒ 引擎 ⇒ 爬虫中间件 ⇒ 爬虫
  4. 爬虫提取 URL 地址,组装成 Requests 对象 ⇒ 爬虫中间件 ⇒ 引擎 ⇒ 调度器,重复步骤2
  5. 爬虫提取数据 ⇒ 引擎 ⇒ 管道处理和保存数据

注意:

  1. 图中中文是为了方便理解后加上去的
  2. 图中 绿色线条 的表示数据的传递
  3. 注意图中中间件的位置,决定了其作用
  4. 注意其中引擎的位置,所有的模块之前相互独立,只和引擎进行交互

Scrapy 中每个模块的具体作用:

1.2 Scrapy 安装和配置

Scrapy文档地址

在使用 Scrapy 前需要安装 Scrapy ,如果读者使用的是 Anaconda Python 开发环境,可以使用下面的命令安装 Scrapy。

conda install scrapy
1

如果读者使用的是标准的 Python 开发环境,可以使用下面的命令安装 Scrapy。

# windows 安装命令如下 加上 --user 防止用户权限不够:
pip install --user -i http://pypi.douban.com/simple --trusted-host pypi.douban.com Scrapy
12

建议在所有平台上的虚拟环境中安装 Scrapy,笔者这里以 Windows 为例,如下:

(1) 创建新的虚拟环境


(2) 在虚拟环境中安装 Scrapy


安装完后,输入下面的语句,如果未抛出异常,说明 Scrapy 已经安装成功。

1.3 Scrapy Shell 抓取 Web 资源

Scrapy 提供了一个 Shell 相当于 Python 的 REPL 环境,可以用这个 Scrapy Shell 测试 Scrapy 代码。在 Windows 中打开黑窗口,执行 scrapy shell 命令,就会进入 Scrapy Shell。

Scrapy Shell 和 Python 的 REPL 环境差不多,也可以执行任何的 Python 代码,只是又多了对 Scrapy 的支持,例如,在 Scrapy Shell 中输入 10 + 20,然后回车,会输出 30,如下图所示:

Scrapy 主要是使用 Xpath 过滤 HTML 页面的内容。那么什么是 XPath 呢? 也就是类似于路径的过滤 HTML 代码的一种技术,关于 XPath 的内容后面再详细讨论。这里不需要了解 XPath 的细节,因为 Chrome 可以根据 HTML 代码的某个节点自动生成 Xpath 。

现在先体验什么叫XPath。启动 Chrome 浏览器,进入 淘宝首页 然后在页面右键菜单中单击 检查 命令,在弹出的调试窗口中选择第一个 Elements 标签页,最后单击 Elements 左侧黑色箭头的按钮,将鼠标放到淘宝首页的导航条 聚划算 上,如下图所示。


这时,Elements 标签页中的 HTML 代码会自动定位到包含 聚划算 的标签上,然后在右键菜单中单击如下图所示的 Copy ⇒ Copy Xpath命令,就会复制当前标签的 Xpath。


很明显,包含 聚划算 文本的是一个 a 标签,复制的 a 标签的 Xpath 如下:

/html/body/div[3]/div/ul[1]/li[2]/a
1

根据这个 XPath 代码就可以基本猜出 XPath 到底是怎么回事。XPath 通过层级的关系,最终指定了 a 标签,其中 li[....] 这样的标签表示父标签不止有一个 li 标签,[...] 里面是索引,从 1 开始。

现在可以在 Chrome上测试一下这个 XPath,单击 Console 标签页,在 Console 中输人如下的代码会过滤出包含 聚划算 的 a 标签。

$x('/html/body/div[3]/div/ul[1]/li[2]/a')
1

如果要过滤出 a 标签里包含的 聚划算 文本,需要使用 XPath 的 text 函数。

$x('/html/body/div[3]/div/ul[1]/li[2]/a/text()')
1

下图是在 Console 中执行的结果,这里就不展开了,因为Chrome 会列出很多辅助信息,这些信息大多用处不大。


为了在 Scrapy Shell 中测试,需要使用下面的命令重新启动 Scrapy Shell。

scrapy shell https://www.taobao.com
1


在 Scrapy Shell 中要使用 response.xpath 方法测试 Xpath 。

response.xpath('/html/body/div[3]/div/ul[1]/li[2]/a/text()').extract()
1

上面的代码输出的是一个列表,如果要直接返回 聚划算 ,需要使用下面的代码:

response.xpath('/html/body/div[3]/div/ul[1]/li[2]/a/text()').extract()[0]
1

从包含 聚划算 的 a 标签周围的代码可以看出,li[1] 表示 天猫,li[3] 表示 天猫超市,所以使用下面两行代码,可以分别得到 天猫 和 天猫超市。

# 输出 "天猫"
response.xpath('/html/body/div[3]/div/ul[1]/li[1]/a/text()').extract()[0]
# 输出 "天猫超市"
response.xpath('/html/body/div[3]/div/ul[1]/li[3]/a/text()').extract()[0]

在 Scrapy Shell 中输入上面 4 条语句的输出结果 如下图所示:

2. 用 Scrapy 编写网络爬虫

2.1 创建和使用 Scrapy 工程

Scrapy 框架提供了一个 scrapy 命令用来建立 Scrapy 工程,可以使用下面的命令建立一个名为 myscrapy 的 Scrapy 工程。

scrapy startproject myscrapy
1


通过命令创建出爬虫文件,爬虫文件为主要的代码作业文件,通常一个网站的爬取动作都会在爬虫文件中进行编写。命令如下:

cd myscrapy
scrapy genspider first_spider www.jd.com

 


生成的目录和文件结果如下:


在 spiders 目录中建立了一个 first_spider.py 脚本文件,这是一个 Spider 程序,在该程序中会指定要抓取的 Web 资源的 URL。示例代码如下:

import scrapy


class FirstSpiderSpider(scrapy.Spider):
    name = 'first_spider'  # Spider的名称 需要该名称启动Scrapy
    allowed_domains = ['www.jd.com']
    start_urls = ['http://www.jd.com/']  # 指定要抓取的Web资源的 URL

    # 每抓取一个URL对应的 Web资源,就会调用该方法,通过response参数可以执行 Xpath过滤标签
    def parse(self, response):
        # 输出日志信息
        self.log('hello world')



现在从终端进到最上层的 myscrapy 目录,然后执行下面的命令运行 Scrapy。

scrapy crawl first_spider
1

执行的结果如下图所示:


运行 Scrapy 后的输出结果中的 Debug 消息输出了 hello world,这就表明了 parse 方法运行了,从而说明 URL 指定的 Web 资源获取成功了。

2.2 Pycharm 中调试 Scrapy 源码

为了直接能在 Python 工程中运行网络爬虫及调试,需要在 myscrapy 根目录中建立一个 main.py(文件名可以任意起) 文件,然后输入下面的代码。

from scrapy.cmdline import execute

import os
import sys

sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# 如果要运行其他的网络爬虫,只需修改上面代码中字符串里面的命令即可
execute(["scrapy", "crawl", "first_spider"])

现在执行 main.py 脚本文件,会在 PyCharm 中的 Run 输入下图所示的信息,从输出的日志信息中同样可以看到 hello world。

2.3 在 Pycharm 中使用扩展工具运行 Scrapy 工具

在 2.2 中编写了一个 main.py 文件用于运行 Scrapy 程序。其实本质上也是执行 scrapy 命令来运行 Scrapy 程序。不过每创建一个 Scrapy 工程,都要编写一个 main.py 文件放到 Pycharm 工程中用于运行 Scrapy 程序显得很麻烦,为了在 Pycharm 中更方便地运行 Scrapy 程序,可以使用 Pycharm 扩展工具通过 scrapy 命令运行 Scrapy 程序。

PyCharm 扩展工具允许在 Pycharm 中通过单击命令执行外部命令。首先单击 Pycharm 的 File ⇒ Settings 命令打开 Settings 对话框。


在左侧单击 Tools ⇒ External Tools 节点,会在右侧显示扩展工具列表,如下图所示:


单击之后会弹出下图所示的 Create Tool 对话框。


在 Create Tool 对话框中通常需要填写如下的内容:

  1. Name:扩展工具的名称,本例是 runscrapy,也可以是任何其他的名字。
  2. Description:扩展工具的描述,可以任意填写,相当于程序的注释。
  3. Program:要执行的程序,本例是 C:\Users\AmoXiang\Envs\spider\Scripts\scrapy.exe,指向 scrapy 命令的绝对路径。读者应该将其改成自己机器上的 scrapy 文件的路径
  4. Arguments :传递给要执行程序的命令行参数。本例是 crawl $FileNameWithoutExtension$,其中$FileNameWithoutExtension$ 是 PyCharm 中的环境变量,表示当前选中的文件名(不包含扩展名),如当前文件名为first_spider.py,选中该文件后,$FileNameWithoutExtension$ 的值就是 first_spider。
  5. Working directory: 工作目录,本例为 $FileDir$/../..。其中 $FileDir$ 表示当前选中文件所在的目录。由于 Scrapy工程中所有的爬虫代码都在 spiders 目录中,所以需要选中 spiders 目录中的爬虫脚本文件(.py文件),才能使用扩展工具运行爬虫。对于用 scrapy 生成的 Scrapy 工程来说,spiders 目
    录位于最内层,所以通常设置工作目录向上反两层。所以Working directory 的值也可以是 $FileDir$/.. 或 $FileDir$。


添加完扩展工具后,选择 spiders 目录中的一个爬虫文件,如 first_spider.py ,然后在右键菜单中单击 External Tools ⇒ runscrapy 命令运行 first_spider.py,会在控制台输出和上面相同的信息。

到这里就结束了,你学会了吗

此文转载于:Amo Xiang   著作权归作者所有,如有侵权联系小编删除!

完整项目代码这里打包好了

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值