学科分类
目录
网络爬虫

制作Spiders爬取网页

使用Scrapy框架制作爬虫的第三步就是制作Spiders,也就是负责爬取和提取数据的爬虫。我们把制作Spiders分为三个步骤实现,分别是创建爬虫、运行爬虫以爬取网页、和提取数据。接下来就对这三个步骤进行详细介绍。

1. 创建爬虫

首先要在项目中创建一个爬虫,创建爬虫的命令格式如下:

scrapy genspider 爬虫名称 "爬取域"

在创建爬虫的命令中,我们需要为爬虫起一个名称,并规定该爬虫要爬取的网页域范围,也就是爬取域。

打开终端,来到当前目录的子目录mySpider/spiders,使用创建爬虫的命令创建一个名为itcast的爬虫,并指定爬取域的范围为“itcast.cn”,具体如下。

scrapy genspider itcast "itcast.cn"

命令行提示,已经使用模板创建了爬虫itcast,如图1所示。

img

图1 创建爬虫

在PyCharm中打开mySpider/spiders目录,可以看到新创建的爬虫文件itcast.py,该文件的内容已经自动生成,具体如下所示。

# -*- coding: utf-8 -*-
import scrapy
class ItcastSpider(scrapy.Spider):
  name = 'itcast'
  allowed_domains = ['itcast.cn']
  start_urls = ['http://itcast.cn/']
  def parse(self, response):
     pass

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

从代码中可以看到,自动创建的爬虫类名称是ItcastSpider,它继承自scrapy.Spider类。scrapy.Spider是Scrapy提供的爬虫基类,我们创建的爬虫类都需要从该类继承。爬虫类中需要定义三个属性(name,allowed_domains和start_urls)和一个方法(parse),这些属性和方法的介绍如下所示。

(1) name属性:表示这个爬虫的识别名称。爬虫的名称必须是唯一的,不同的爬虫需要定义不同的名称。

(2) allow_domains属性:表示爬虫搜索的域名范围,也就是爬虫的约束区域。该属性规定爬虫只能爬取这个域名下的网页,不在该域名下的URL会被忽略。

(3)start_urls属性:表示爬取的起始URL元组或列表。爬虫第一次下载的数据将会从这些URL开始,其它子URL将会从这些起始URL中继承性地生成。

(4)parse(self, response)方法:用于解析网络响应。该方法在每个初始URL完成下载后被调用,调用的时候传入从该URL返回的Response对象做为唯一参数。parse方法主要有两个功能,包括:

  • 解析返回的网页数据(response.body),提取结构化数据(生成item)。

  • 生成访问下一页数据的URL请求。

接下来,我们对生成的ItcastSpider类进行自定义修改。首先将start_urls的值修改为需要爬取的第一个URL,代码如下所示。

start_urls = ("http://www.itcast.cn/channel/teacher.shtml",)

然后修改parse方法,在该方法中将响应信息转换成文本,保存在tearcher.html文件中。代码如下所示。

def parse(self, response):
  with open("teacher.html", "w", encoding="utf-8") as file:
     file.write(response.text)

2. 运行爬虫,爬取网页

ItcastSpider类的代码修改完成后,接下来就可以运行itcast爬虫来爬取网页了。运行爬虫的命令格式为:

scrapy crawl 爬虫名称

我们在终端中进入itcast.py文件所在的目录,执行如下命令。

scrapy crawl itcast

上述命令里的itcast就是ItcastSpider类的name属性的值,也是使用scrapy genspider命令时确定的爬虫名称。

一个Scrapy爬虫项目里,可以存在多个爬虫,各个爬虫在执行时,就是按照name属性来区分的。

命令执行之后,如果打印的日志出现如下提示信息,则代表爬取过程执行完毕。

[scrapy.core.engine] INFO: Spider closed (finished)

之后当前文件夹就会出现一个teacher.html文件,文件内容就是我们使用爬虫itcast爬取到的网页的全部源代码信息。图2是该文件的部分内容。

img

图2 teacher.html文件的部分内容

3. 提取数据

通过前面两个步骤,我们已经成功爬取到了网页的源码,接下来就可以从源码中提取数据。要提取数据,首先需要观察页面源码,定位目标数据,分析和了解目标数据的展示结构,如图3所示。

img

图3 观察页面源码,定位目标数据

从源码中分析的结果是,每个讲师的信息都包含在一个div里,该div展示了讲师的名称、级别和个人信息,其结构如下所示。

<div class="li_txt">
  <h3>讲师名称</h3>
  <h4>讲师级别</h4>
  <p>讲师个人信息</p>
</div>

分析并了解到目标数据的展示结构之后,就可以使用Scrapy支持的Xpath解析方式进行数据提取了。

我们之前在项目的mySpider/items.py目录下定义了MyspiderItem类,需要将该类引入到itcast.py文件中,代码如下。

from mySpider.items import MyspiderItem

然后修改ItcastSpider类的parse方法,将得到的数据封装成一个MyspiderItem对象,每个对象保存一个讲师的信息,然后将所有的对象保存在一个列表items里。代码如下所示。

  def parse(self, response):
     items = [] #存放老师信息的集合
     for each in response.xpath("//div[@class='li_txt']"):
       # 将我们得到的数据封装到一个'MyspiderItem'对象
       item = MyspiderItem()
       # extract方法返回的都是Unicode字符串
       name = each.xpath("h3/text()").extract()
       title = each.xpath("h4/text()").extract()
       info = each.xpath("p/text()").extract()
       # XPath返回的是包含一个元素的列表
       item["name"] = name[0]
       item["title"] = title[0]
       item["info"] = info[0]
       items.append(item)
     # 返回数据,不经过pipeline
     return items

此时在命令行中使用“scrapy crawl itcast”命令再次运行爬虫,就可以看到控制台打印出获取到的讲师信息。部分打印信息如图4所示。

img

图4 获取到的部分目标数据

多学一招:在PyCharm中执行爬虫项目

到现在为止,都是在命令行中输入命令来执行爬虫项目。我们可能会想,如果能够通过PyCharm来执行项目,不是更加简单吗?其实是可以实现的,只需要以下几个步骤。

(1)在PyCharm中打开项目,在项目中添加一个文件,取名为start.py,内容为:

from scrapy import cmdline
cmdline.execute("scrapy crawl itcast".split())

这个文件的内容就调用了命令行来执行语句。

(2)在PyCharm中运行start.py文件,就可以了。这样就不用每次再手动通过命令行来运行了。

点击此处
隐藏目录