scrapy框架入门

scrapy框架入门

一、Scrapy框架介绍

1.框架简介

  • Scrapy是纯Python开发的一个高效,结构化的网页抓取框架
  • Scrapy使用了Twisted 异步网络库来处理网络通讯
  • Scrapy是为了爬取网站数据,提取结构性数据而编写的应用框架
  • Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试

2.模块安装

scrapy支持Python2.7和python3.4以上版本

python包可以用全局安装(也称为系统范围),也可以安装在用户空间中

(1).Windows

pip install scrapy

换源:

pip install scrapy -i https://pypi.doubanio.com/simple

如果安装途中报错,则按照以下方法安装

  1. https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载对应的Twisted的版本文件
  2. 在命令行进入到Twisted的目录,执行pip install Twisted的文件名
  3. 执行pip install scrapy
(2).Ubuntu 14.04或以上

scrapy目前正在使用最新版的lxml,twisted和pyOpenSSL进行测试,并且与最近的Ubuntu发行版兼容,但它也支持旧版本的Ubuntu,比如Ubuntu14.04,尽管可能存在TLS连接问题

Ubuntu安装不要使用 python-scrapyUbuntu提供的软件包,它们通常太旧而且速度慢,无法赶上最新的Scrapy

  • 在Ubuntu(或基于Ubuntu)系统上安装scrapy,需要安装这些依赖项:

    sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev

  • 如果想在python3上安装scrapy,还需要Python3的开发头文件:

    sudo apt-get install python3-dev

  • 在virtualenv中,可以使用pip安装Scrapy:

    pip install scrapy

3.架构介绍

在这里插入图片描述

  • Engine:引擎。负责控制系统所有组件之间的数据流,并在发生某些操作时触发事件,是整个框架的核心

  • Spiders:蜘蛛。由用户编写的自定义的类,用于解析响应,从中提取数据,或其它要抓取的请求

  • Scheduler:调度器。接收来自引擎的请求并将其排入队列,在引擎再次请求时将请求提供给引擎

  • Downloader:下载器。获取网页并将其提供给引擎,引擎再将网页内容提供给spider

  • Item Pipeline:项目管道。负责由爬虫提取的数据的后续处理,典型的任务包括清理、验证和存储数据

  • Spider Middlewares:蜘蛛中间件。位于引擎和爬虫之间的特定的钩子,负责处理向蜘蛛输入的响应和输出的结果及新的请求。以下情况使用爬虫中间件:

    • 处理爬虫回调之后的请求或item
    • 处理start_requests
    • 处理爬虫异常
    • 根据响应内容调用errback而不是回调请求
  • Downloader Middlewares:下载中间件。位于引擎和下载器之间的特定的钩子,负责处理从引擎传递到下载器的请求,以及下载器传递到引擎的响应。以下情况使用下载中间件:

    • 在请求发送到下载程序之前处理请求(即在scrapy将请求发送到网站之前)
    • 在响应发送给爬虫之前
    • 直接发送新的请求,而不是将收到的响应传递给蜘蛛
    • 将响应传递给爬行器而不获取web页面;
    • 默默的放弃一些请求
  • Items:项目。定义了爬取结果的数据结构,爬取的数据会被赋值成该Item对象

  • Internet:事件驱动的网络。scrapy 是用Twisted编写的,Twisted是一个流行的事件驱动的Python网络框架,它使用非阻塞(也成为异步)代码实现并发

4.运行流程

Scrapy中的数据流由执行引擎控制,流程如下:

  1. Engine首先向Spiders请求第一个要爬取的URL,URL通过Spiders到达Engine之后,Engine将URL转发给Scheduler以Request的形式调度
  2. Engine从Scheduler请求下一个要爬取的Request,Engine获得Request之后,通过下载中间件转发给Downloader,Downloader连接互联网并爬取相关的网页形成Response,并将其通过下载中间件发送给Engine,再由Engine转发到Spiders
  3. Spiders处理接收到的Response,然后解析出Item和生成新的Request,并发送给Engine,Engine将处理好的Item发送给Item Pipeline,将生成好的新的Request发送给调度器

5.项目结构

scrapy.cfg			# Scrapy项目的配置文件,定义了项目配置文件路径、部署相关信息等内容
project/			# 项目模块
	__init__.py
	items.py			# 定义Item的数据结构
	pipelines.py		# 定义Item Pipeline的实现
	settings.py			# 定义项目的全局配置
	middlewares.py		# 定义爬虫中间件和下载中间件的实现
	spiders/			# 防止spider的文件夹
		__init.py	
		spider1.py			# spider1文件
		spider2.py			# spider2文件
        ...

二、Scrapy入门(爬取腾讯课堂所有python课程信息)

1.创建项目

进入你想要存放项目的目录下运行一下命令:

scrapy startproject 项目名

例如:scrapy startproject tencent

该命令会在当前目录创建包含一下文件的名为tz_spider的目录

2.创建Spider

Spider是自己定义的类,Scrapy用它从网页里抓取内容并解析抓取的结果。创建一个Spider的类,它必须必须继承Scrapy提供的Spider类scrapy.Spider,并且需要定义三个属性:

  • name:用于区别Spider,该名字必须是唯一的
  • start_urls:包含了Spider在启动时进行爬取的url列表 ,初始请求由它定义
  • parse(self, response) 方法:Spider的一个方法,每个初始url完成之后被调用。这个函数要完成两个功能:
    1. 解析响应,封装成item对象并返回这个对象
    2. 提取新的需要下载的url,创建新的request,并返回它

可以使用命令行创建一个spider:

cd 项目文件

scrapy genspider <name> <domain>

例如:

cd tencent

scrapy genspider ke ke.qq.com

会在spiders文件下创建ke.py文件,文件内容如下:

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


class KeSpider(scrapy.Spider):
    name = 'ke'
    allowed_domains = ['ke.qq.com']
    start_urls = ['http://ke.qq.com/']

    def parse(self, response):
        pass
  • allowed_domains:允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则会被过滤掉,一般将其注释掉

3.定义Items文件

Item是保存爬取数据的容器,使用方法类似于字典,比字典多了额外的保护机制,避免拼写错误或者定义字段错误。创建Item类需要继承scrapy.Item类,并且定义类型为scrapy.Field的字段

items.py文件,内容如下:

import scrapy


class KeItem(scrapy.Item):
    title = scrapy.Field()
    link_url = scrapy.Field()
    img_url = scrapy.Field(

4.解析Response

parse()方法的参数response是start_urls里面的链接爬取后的结果,所以可以在parse()方法中直接对response进行解析,extract()方法把selectlist对象序列成字符串

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


class KeSpider(scrapy.Spider):
    name = 'ke'
    # allowed_domains = ['ke.qq.com']
    start_urls = ['https://ke.qq.com/course/list']

    def parse(self, response):
        title_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/h4/a/text()').extract()
        link_url_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/a/@href').extract()
        img_url_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/a/img/@src').extract()

5.使用Item

Item可以理解为一个字典,但在声明的时候需要实例化,因此首先导入该类,接下来进行实例化,然后依次用刚才解析的结果赋值给Item的每个字段,最后将Item通过yield返回即可。这样首页的所有内容都被解析出来,并且复制成一个个的KeItem()

# -*- coding: utf-8 -*-
import scrapy
from ..items import KeItem


class KeSpider(scrapy.Spider):
    name = 'ke'
    # allowed_domains = ['ke.qq.com']
    start_urls = ['https://ke.qq.com/course/list']

    def parse(self, response):
        title_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/h4/a/text()').extract()
        link_url_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/a/@href').extract()
        img_url_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/a/img/@src').extract()
        for title, link_url, img_url in zip(title_list, link_url_list, img_url_list):
            item = KeItem()
            item['title'] = title
            item['link_url'] = link_url
            item['img_url'] = img_url
            yield item

6.后续Request

上面的爬虫实现了从初始页面抓取内容,而我们需要爬取所有页面,直到所有的信息都被下载。因此需要从页面中提取链接,或者根据规则构建(小技巧:开发者工具下点击下一页那个标识)。构造请求时候需要用到scrapy.Request(),传入两个参数:

  • url:请求链接
  • callback:回调函数。当指定了该回调函数的请求完成后,获取到响应,引擎会将该响应作为参数传递给此回调函数,回调函数进行解析或生成下一个请求
# -*- coding: utf-8 -*-
import scrapy
from ..items import KeItem


class KeSpider(scrapy.Spider):
    name = 'ke'
    # allowed_domains = ['ke.qq.com']
    start_urls = ['https://ke.qq.com/course/list']

    def parse(self, response):
        title_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/h4/a/text()').extract()
        link_url_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/a/@href').extract()
        img_url_list = response.xpath('//ul/li[@class="course-card-item--v3 js-course-card-item "]/a/img/@src').extract()
        for title, link_url, img_url in zip(title_list, link_url_list, img_url_list):
            item = KeItem()
            item['title'] = title
            item['link_url'] = link_url
            item['img_url'] = img_url
            yield item

        next_url = response.xpath('//a[@class="page-next-btn icon-font i-v-right"]/@href').extract_first()		# 此处需要调用extract_first()方法获取获取内容
        if next_url:		# next_url为空时停止,否则报错
            yield scrapy.Request(url=next_url, callback=self.parse)	# 回调函数依然使用parse()方法,不写默认也是parse()方法

7.运行

进入项目根目录(tencent)下,在命令行运行命令:

查看可运行的爬虫文件:

scrapy list

运行爬虫:

scrapy crawl <name>

注意:此处的name是创建Spider时的name属性,而不是.py文件的文件名

例如:scrapy crawl ke

8.保存到文件

以下命令对应的输出分别为json、csv、xml、pickle、marshal格式

scrapy crawl ke -o ke.json
scrapy crawl ke -o ke.csv
scrapy crawl ke -o ke.xml
scrapy crawl ke -o ke.pickle
scrapy crawl ke -o ke.marshal

9.定义Item Pipeline

如果想进行更复杂的操作(将结果保存到数据库,或者筛选信息),则需要定义Item Pipeline来实现

Item Pipeline的主要用途是:

  • 清理HTML数据
  • 验证爬取数据,检查爬取字段
  • 查重并删除重复内容
  • 将爬取结果保存到数据库

要激活这个管道组件,必须将其添加到ITEM_PIPELINES设置中,在settings文件中设置如下:

ITEM_PIPELINES = {
   'tencent.pipelines.TencentPipeline': 300,
}

编写一个用来存储课程信息到ke.json文件中的管道类,修改项目下piplines.py文件

import json


class TencentPipeline(object):
    def open_spider(self, spider):
        # 在爬虫启动时打开文件
        # 打开文件句柄
        self.f = open('ke.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        # 处理传递过来的item
        self.f.write(json.dumps(dict(item), ensure_ascii=False, indent=4) + "\n")
        return item

    def close_spider(self, spider):
        # 在爬虫关闭时关闭文件
        self.f.close()


self.f = open(‘ke.json’, ‘w’, encoding=‘utf-8’)

def process_item(self, item, spider):
    # 处理传递过来的item
    self.f.write(json.dumps(dict(item), ensure_ascii=False, indent=4) + "\n")
    return item

def close_spider(self, spider):
    # 在爬虫关闭时关闭文件
    self.f.close()



  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值