从零开始写Python爬虫 --- 2.2 Scrapy 选择器和基本使用

从零开始写Python爬虫 --- 2.2 Scrapy 选择器和基本使用

在正式使用Scrapy框架之前,我们必须先了解它是如何筛选数据的,Scrapy有自己的一套数据选择器,比如Xpath和CCSS选择器。并且这些选择器构造于‘lxml’之上,这就意味着Scrapy框架下的数据筛选有着很高的效率。

基本选择器:

Scrapy爬虫支持多种信息提取的方法:

  • Beautiful Soup
  • Lxml
  • re
  • XPath Selector
  • CSS Selector

在前面的爬虫实例中,我们大量的使用了bs4选择器,所以这里我就不过多介绍了。这里我主要说一下关于Xpath的使用。

首先介绍一下XPath:

XPath 是一门在xml文档中查找信息的语言,它可以在XML文档中对于原色和属性进行遍历。其内置了超过100个内建函数,这些函数用于对字符串值,数值、日期、时间进行比较遍历。总之是一门很方便的语言。如过要具体学习请看
菜鸟教程-Xpath:XPath 教程 | 菜鸟教程
在网络爬虫中,我们只需要利用XPath来采集数据,所以只要掌握一些基本语法,就可以上手使用了。


基本使用语法:

直接看这个表:


实例介绍:

下面我们将以这个demo.xml为例子来介绍:

<html>
    <body>
        <class>
            <name>王尼玛</name>
            <sex></sex>
            <age>80</age>
            <favouite>开车</favouite>
        </class>
        <class>
            <name>陈一发</name>
            <sex></sex>
            <age>28</age>
            <favouite>开che</favouite>
        </class>
        <class>
            <name>狗贼叔叔</name>
            <sex></sex>
            <age>18</age>
            <favouite>土豪战</favouite>
        </class>
    </body>
</html>

先将我们需要使用的模块导入(调试环境为ipython):

In [1]: from scrapy.selector import Selector

In [2]: body = open('demo.xml','r').read()

In [3]: print(body)
<html>
    <body>
        <class>
            <name>王尼玛</name>
            <sex></sex>
            <age>80</age>
            <favouite>开车</favouite>
        </class>
        <class>
            <name>陈一发</name>
            <sex></sex>
            <age>28</age>
            <favouite>che</favouite>
        </class>
        <class>
            <name>狗贼叔叔</name>
            <sex></sex>
            <age>18</age>
            <favouite>土豪战</favouite>
        </class>
    </body>
</html>

In [4]: body
Out[4]: '<html>\n    <body>\n        <class>\n            <name>王尼玛</name>\n            <sex>男</sex>\n            <age>80</age>\n            <favouite>开车</favouite>\n        </class>\n        <class>\n            <name>陈一发</name>\n            <sex>母</sex>\n            <age>28</age>\n            <favouite>开che</favouite>\n        </class>\n        <class>\n            <name>狗贼叔叔</name>\n            <sex>公</sex>\n            <age>18</age>\n            <favouite>土豪战</favouite>\n        </class>\n    </body>\n</html>'

In [5]: 

下面我们来举几个小例子,说明一下如何通过xpath找到我们想要的数据:


在Xpath中最常用的方法大该就是这些了,

如果你还是不太习惯Xpath的用法,你依旧可以通过老的bs4库的方式去筛选数据。


Scrapy框架的具体使用:

我们来通过一个super简单的例子来介绍Scrapy框架的使用,
第一个例子本着越简单越好的原则,帮助大家快速入门,
当然,如果不满足于简单例子,可以自己动手diy一些新的功能进去,
我们要爬的网址是:字幕库: zimuku.net
为了简便,我们只准备抓取字幕标题

步骤一:创建一个工程和Spider模板

我们先用命令行创建一个Scrapy工程:

scrapy startproject zimuku


接着,我们进入到工程目录:

cd zimuku


我们来看一下目录结构:

tree
# OUT:
.
├── zimuku                  #外层目录
│   ├── __init__.py         #初始化脚本    
│   ├── __pycache__         #Python缓存文件。暂时无视
│   ├── items.py            #Items代码模板,继承类自scrapy.Item
│   ├── middlewares.py      #Middlewares代码模板(继承类)
│   ├── pipelines.py        #Pipelines代码模板(继承类)
│   ├── settings.py         #Scrapy爬虫的配置文件
│   └── spiders             #Spiders代码模板目录 我们写爬虫的地方
│       ├── __init__.py
│       └── __pycache__
└── scrapy.cfg              #部署爬虫的配置文件

4 directories, 7 files

最后,我们用命令行创建第一个Spider:
scrapy genspider demo zimuku.net
这样我们就创建了一个名为demo的爬虫了。

我们来看看他长什么样,打开/spiders/demo.py:

# -*- coding: utf-8 -*-
import scrapy
class DemoSpider(scrapy.Spider):
    name = "demo"
    allowed_domains = ["zimuku.net"]
    start_urls = ['http://zimuku.net/']
    def parse(self, response):
        pass

可以看到,Scrapy已经帮我们把爬虫的框架写好了,我们只要在这个框架的基础上进行进一步的定制就可以了。

步骤二:编写Spider

我们来着手定制我们的爬虫吧:
看一下详细的注释

# -*- coding: utf-8 -*-
import scrapy

# 将我们需要爬的项目引入进来
from zimuku.items import ZimukuItem

class DemoSpider(scrapy.Spider):
    
    #该爬虫的名字
    name = "demo"
    
    #规定爬虫爬取网页的域名   
    allowed_domains = ["zimuku.net"]
    
    #开始爬取的url链接
    start_urls = ['http://zimuku.net/']

    def parse(self, response):
        '''
        parse()函数接收Response参数,就是网页爬取后返回的数据
        用于处理响应,他负责解析爬取的内容
        生成解析结果的字典,并返回新的需要爬取的请求
        '''

        #由于是demo 我们不做完全的功能,
        #只要求爬取出第一个字幕的名字
        #xpath规则可以通过查看网页源文件得出
        name = response.xpath('//b/text()').extract()[1]

        #建立一个items字典,用于保存我们爬到的结果,并返回给pipline处理
        items = {}
        items['第一个']= name

        return items

步骤三:编写Item Pipeline

首先我们编写itmes.py来定义这个爬虫框架需要爬哪些内容:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy
class ZimukuItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    subname = scrapy.Field() #字母的名字

接着我们编写 piplines.py来处理spider爬到的内容:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
class ZimukuPipeline(object):
    def process_item(self, item, spider):

        # 只要求简单的话,
        # 我们把爬到的结果打印一下吧
        print(item)

        return item

步骤四:优化配置Settings.py

BOT_NAME = 'zimuku'

SPIDER_MODULES = ['zimuku.spiders']
NEWSPIDER_MODULE = 'zimuku.spiders'
ROBOTSTXT_OBEY = True
#只增加了这一行,通过配置告诉Scrapy明白是谁来处理结果
ITEM_PIPELINES={'zimuku.pipelines.ZimukuPipeline':300,}

结果:

首先我们通过命令来执行爬虫:

scrapy crawl demo


让我们这个最最简单的爬虫跑起来。

来看一下结果:
截取部分:

2017-05-11 21:29:42 [scrapy.core.scraper] DEBUG: Scraped from <200 http://www.zimuku.net/>
{'第一个': '绿箭侠 第五季(第21集-简繁英双语字幕)Arrow.S05E21.720p.HDTV.x264-SVA.zip'}


可以看到我们已经找到了我们想要的内容了。

好了,通过这个super简单的小例子,我们知道了Scrapy框架到底是如何运作的,
但是这真的是简单到不能再简单的例子,更多的用法,我会在以后的实例中进行展开~


每天的学习记录都会 同步更新到:
微信公众号: findyourownway

知乎专栏:从零开始写Python爬虫 - 知乎专栏

blog : www.ehcoblog.ml

Github: Ehco1996/Python-crawler

编辑于 2017-05-15

文章被以下专栏收录