Python爬虫学习笔记 2-1:Scrapy框架
Published On 2019/11/17 Sunday, Singapore
前面章节主要用到Requests的方式爬取网页。在小规模爬虫时,Requests能够有效地满足需求,但大规模多线程的爬虫时则需要使用Scrapy。本节讲解Scrapy爬虫的基本框架, 安装和基本使用。
本文为Datacatsle Python爬虫(入门+进阶)课程学习笔记。
什么是Scrapy框架?
Scrapy是一个为了爬取网页信息并提取结构性数据而编写的应用框架。也可以应用在获取API所返回的数据(例如Amazon Associates Web Services)。Scrapy因其抓取和解析的速度而广受欢迎。多线程下载器和异步调度处理使其爬取速度非常快。另外它还具有内置的logging,exception,shell等。具体来说,Scrapy包含以下组件:
- 引擎(Engine):用来处理整个系统的数据流,触发事务。
- 调度器(Scheduler):用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。可以想像成一个网页网址的优先队列,由它来决定下一个要抓取的网址是什么,同时去除重复的网址。
- 下载器(Downloader):用于下载网页内容,并将网页内容返回给引擎。
- 爬虫(Spiders):用于从特定的网页中提取需要的信息,同时也可以提取出下一页面的链接。
- 项目管道(Item Pipelines):负责处理爬虫获得的信息,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据,并保存数据。
- 下载器中间件(Downloader Middlewares):位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应,是进行反反爬工作的重点。同时在拿到数据后,验证拿到的数据不为空,并且正常。
- 爬虫中间件(Spider Middlewares):介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
Scrapy的安装
在cmd/terminal中,输入以下命令安装scrapy
。
pip install scrapy
在window下如果你使用Anaconda,也可以打开Anaconda prompt:
conda install scrapy
在windows下,可能遇到依赖包无法安装的问题。这时候可以进入非官方安装包下载依赖包对应版本的.whl文件,使用pip install 文件地址+文件名的方式进行安装。
Scrapy的基本使用
一个基本的爬虫只需要两部分组成:爬虫(Spider)和 管道(Pipeline)。爬虫定义了如何爬取网站,包括了爬取的操作以及如何从网页的内容中提取结构化数据。管道是一个实现简单方法的类。他们接收一个项目并对其执行操作,还决定该项目是否应该继续通过流水线或被丢弃并且不再被处理。项目管道的典型用途是:
- 清理HTML数据
- 验证抓取的数据(检查项目是否包含特定字段)
- 检查重复(并删除)
- 将抓取的项目存储在数据库中
现在,我们以爬去58同城为例来看看scrapy的基本使用。
第一步,新建Scrapy项目
通过cmd/terminal运行以下命令新建一个scrapy项目,名为city_58
。
scrapy startproject city_58
运行结果如下:
打开/User/joye/city58
查看scrapy
项目文件。其包含一个city_58
的子文件夹和一个名为scrapy.cfg
的项目配置文件。city_58子文件夹为该项目的python模块,之后我们将在此加入代码。
city_58
子文件夹下面包含:
spiders
:放置spider代码的目录。主要是用于分析response并提取返回的item或者是下一个URL信息,每个Spider负责处理特定的网站或一些网站。__init__.py
: 初始化文件。-
items.py
: 定义我们所要爬取的信息的相关属性。Item对象是种容器,用来保存获取到的数据。通过里面的注释可见,这个文件的作用是定义我们要爬取信息的标准格式。比如定义姓名,性别,生日。# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.html import scrapy class City58Item(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() pass
-
settings.py
:项目的设置文件。通过在此文件中的设置可以控制包括核心、插件、pipeline以及Spider组件。此处先看看默认打开的配置项。因为是定向爬虫,前面三个按默认即可。看第四项,注释里说这个配置项的意思是遵守robots.txt,如果不遵守的话可以设置为False。# -*- coding: utf-8 -*- # Scrapy settings for city_58 project # # For simplicity, this file contains only settings considered important or # commonly used. You can find more settings consulting the documentation: # # https://docs.scrapy.org/en/latest/topics/settings.html # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html # https://docs.scrapy.org/en/latest/topics/spider-middleware.html BOT_NAME = 'city_58' SPIDER_MODULES = ['city_58.spiders'] NEWSPIDER_MODULE = 'city_58.spiders' # Crawl responsibly by identifying yourself (and your website) on the user-agent #USER_AGENT = 'city_58 (+http://www.yourdomain.com)' # Obey robots.txt rules ROBOTSTXT_OBEY = True
middlewares.py
: 定义相关的方法,用以处理蜘蛛的响应输入和请求输出。-
pipelines.py
:在item被Spider收集之后,就会将数据放入到item pipelines中,在这个组件是一个独立的类,他们接收到item并通过它执行一些行为,同时也会决定item是否能留在pipeline,或者被丢弃。 注释提醒要启用Pipeline的话必须要在settings.py里配置一下ITEM_PIPELINES. process_item函数可以对爬取到的数据item进行处理(比如存入数据库),或者在爬虫结束时产生事件(比如发送一封邮件)。# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html class City58Pipeline(object): def process_item(self, item, spider): return item
第二步,生成爬虫文件
在cmd/terminal下运行以下命令,切换到city_58文件下。并生产在spider文件夹下生成spider_city_58.py.
cd city_58
scrapy genspider spider_city_58 58.com
spider_city_58.py是一个基于我们输入的爬虫名“spider_city_58”和爬取网站“58.com”,从scrapy包中basic模版中生成的py文件。代码如下:
# -*- coding: utf-8 -*-
import scrapy
class SpiderCity58Spider(scrapy.Spider):
name = 'spider_city_58' #必不可少的属性,需要利用它去决定启动哪个爬虫
allowed_domains = ['58.com']
start_urls = ['http://58.com/'] #从start_urls中启动链接
#默认解析器方法
def parse(self, response):
pass
第三步,启动Scrapy框架
两种启动方法:
-
通过cmd/terminal中执行以下代码:
scrapy crawl spider_city_58
-
在项目中建立一个main.py文件如下,然后运行该文件即可。
#main.py from scrapy import cmdline cmdline.execute("scrapy crawl spider_city_58".split())
现在我们启动爬虫进行测试。为了知道请求到达了默认解析器(parse),在spider_city_58.py
的解析部分打印 “Parse Begin” 。
# -*- coding: utf-8 -*-
import scrapy
class SpiderCity58Spider(scrapy.Spider):
name = 'spider_city_58' #必不可少的属性,需要利用它去决定启动哪个爬虫
allowed_domains = ['58.com']
start_urls = ['http://58.com/'] #从start_urls中启动链接
#默认解析器方法
def parse(self, response):
print('Parse Begin')
html = response.body # response是获取到的来自网站的返回
# 以下四行将html存入文件
filename = "58city.html"
file = open(filename, "w")
file.write(html)
file.close()