scrapy爬虫框架

目录

Scrapy的介绍

Scarpy开发第一个爬虫

 Scrapy项目的启动介绍

Scrapy启动-命令启动 

Scrapy启动-脚本启动 

Scrapy 数据的提取

Scrapy 保存数据到文件 

Item Pipeline的使用 

Scrapy 使用ImagePipeline 保存图片

Scrapy 自定义ImagePipeline 

Scrapy 中settings配置 的使用 

Scrapy 中 Request 的使用


Scrapy的介绍

scrapy爬虫框架_第1张图片

         Scrapy 是一个用于抓取网站和提取结构化数据的应用程序框架,可 用于各种有用的应用程序,如数据挖掘、信息处理或历史存档。 尽管 Scrapy 最初是为网络抓取而设计的,但它也可用于使用 API提取数据或用作通用网络爬虫。

Scrapy的优势

  • 可以容易构建大规模的爬虫项目
  • 内置re、xpath、css选择器
  • 可以自动调整爬行速度
  • 开源和免费的网络爬虫框架
  • 可以快速导出数据文件: JSON,CSV和XML
  • 可以自动方式从网页中提取数据(自己编写规则)
  • Scrapy很容易扩展,快速和功能强大
  • 这是一个跨平台应用程序框架(在Windows,Linux,Mac OS)
  • Scrapy请求调度和异步处理

Scrapy的架构 

scrapy爬虫框架_第2张图片

 最简单的单个网页爬取流程是 spiders > scheduler > downloader > spiders > item pipeline 省略了engine环节!

  • 引擎(engine)
    • 用来处理整个系统的数据流处理, 触发事务(框架核心)
  • 调度器(Scheduler)
    • 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL (抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时 去除重复的网址
  • 下载器(Downloader)
    • 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步 模型上的) 爬虫(Spiders) 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可 以从中提取出链接,让Scrapy继续抓取下一个页面
  • 项目管道(Pipeline)
    • 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需 要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。 
  • 下载器中间件(Downloader Middlewares)
    • 位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应
  • 爬虫中间件(Spider Middlewares)
    • 介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出
  • 调度中间件(Scheduler Middewares)
    • 介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应

安装 

pip install scrapy

Scarpy开发第一个爬虫

scrapy爬虫框架_第3张图片

创建第一个项目

scrapy startproject myfrist(project_name)

scrapy爬虫框架_第4张图片

 文件说明

scrapy爬虫框架_第5张图片

 创建第一个爬虫

scrapy genspider 爬虫名 爬虫的地址

注意:一般创建爬虫文件时,以网站域名命名

爬虫包含的内容

  • name: 它定义了蜘蛛的唯一名称
  • allowed_domains: 它包含了蜘蛛抓取的基本URL;
  • start-urls: 蜘蛛开始爬行的URL列表;
  • parse(): 这是提取并解析刮下数据的方法; 
import scrapy
class DoubanSpider(scrapy.Spider):
    name = 'douban'
    allowed_domains = 'douban.com'
    start_urls = ['https://movie.douban.com/top250/']
    def parse(self, response):
        movie_name = response.xpath("//div[@class='item']//a/span[1]/text()").extract()
        movie_core = response.xpath("//div[@class='star']/span[2]/text()").extract()
        yield {
            'movie_name':movie_name,
            'movie_core':movie_core
       }

 Scrapy项目的启动介绍

scrapy爬虫框架_第6张图片

  • Scrapy启动的方式有多种方式:
    • Scrapy命令运行
      • 运行环境
        • 命令行:cmd/powershell/等等 
    •  运行Python脚本
      • 运行环境
        • 命令行:cmd/powershell/等等
        • 编辑器:VSCode/PyCharm等等

注意 运行程序之前,要确认网站是否允许爬取 robots.txt 文件 

Scrapy启动-命令启动 

scrapy命令 scrapy框架提供了对项目的命令scrapy ,具体启动项目命令格式如 下:

方法1:

scrapy crawl 爬虫名

注意 这的爬虫名是爬虫文件中name属性的值

方法2:

scrapy runspider spider_file.py

 注意 这是爬虫文件的名字 要指定到spider文件夹

Scrapy启动-脚本启动 

Scrapy为开发者设置好了启动好的对象。因此,我们通过脚本即可 启动Scrapy项目

运行脚本

在项目的目录下,创建脚本,比如项目名为:scrapy01,创建脚本 的路径为 scrapy01\scrapy01\脚本.py 

脚本

使用cmdline 

from scrapy.cmdline import execute
execute(['scrapy', 'crawl', '爬虫名字'])

使用CrawlerProcess

from scrapy.crawler import CrawlerProcess
from spiders.baidu import BaiduSpider
process = CrawlerProcess()
process.crawl(BaiduSpider)
process.start()

运行

命令行运行

python 脚本.py

Scrapy 数据的提取

scrapy爬虫框架_第7张图片

Scrapy有自己的数据提取机制。它们被称为选择器。我们可以通过 使用的选择器re、xpath、css提取数据。

提示 不用再安装与引入Xpath,BS4 

获得选择器

Response对象获取

正常使用 

response.selector.xpath('//span/text()').get()
response.selector.css('span::text').get()
response.selector.re('')

快捷使用

response.xpath('//span/text').get()
response.css('span::text').get()

创建对象

from scrapy.selector import Selector

通过text参数 初始化

body = 'good'
Selector(text=body).xpath('//span/text()').get()

通过response参数 初始化

from scrapy.selector import Selector
from scrapy.http import HtmlResponse
response = HtmlResponse(url='http://example.com',body=body)
Selector(response=response).xpath('//span/text()').get()
'good'

选择器的方法

scrapy爬虫框架_第8张图片

Scrapy 保存数据到文件 

scrapy爬虫框架_第9张图片

 1.用Python原生方式保存

with open("movie.txt", 'wb') as f:
    for n, c in zip(movie_name,movie_core):
        str = n+":"+c+"\n"
        f.write(str.encode())

2.使用Scrapy内置方式

scrapy 内置主要有四种:JSON,JSON lines,CSV,XML 最常用的导出结果格为JSON,命令如下:

scrapy crawl dmoz -o douban.json -t json 

参数设置:

  • -o 后面导出文件名
  • -t 后面导出的类型 可以省略,但要保存的文件名后缀,写清楚类型

注意

将数据解析完,返回数据,才可以用命令保存,代码如下,格 式为dict或item类型

  • return data
  • yield data 

Item Pipeline的使用 

scrapy爬虫框架_第10张图片

当数据在Spider中被收集之后,可以传递到Item Pipeline中统一进 行处理

特点

每个item pipeline就是一个普通的python类,包含的方法名如下: 

 scrapy爬虫框架_第11张图片

功能 

  • 1.接收item
    • 在 process_item 方法中保存
  • 2 是否要保存数据
    • 取决于是否编写代码用于保存数据
  • 3 决定此Item是否进入下一个pipeline
    • return item 数据进入下一个pipeline
    • drop item 抛弃数据 

案例代码 

class SaveFilePipeline:
    def open_spider(self,spider):
        self.file = open('douban5.txt','w')
    def process_item(self, item, spider):
        self.file.write(f'name:{item.get("name")} score:{item.get("score")}\n')
    def close_spider(self,spider):
        self.file.close()
from scrapy.exceptions import DropItem
class XSPipeline:
    def open_spider(self,spider):
        self.file = open('xs.txt','w',encoding='utf-8')
    def process_item(self, item, spider):
        if item.get('title'):
            self.file.write(item.get('title'))
            self.file.write('\n')
            return item
        else:
            raise DropItem(f"Missing title in {item}")
    def close_spider(self,spider):
        self.file.close()

Scrapy 使用ImagePipeline 保存图片

scrapy爬虫框架_第12张图片

Scrapy提供了一个 ImagePipeline,用来下载图片这条管道,图片管 道 ImagesPipeline 提供了方便并具有额外特性的功能,比如:

  • 将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
  • 避免重新下载最近已经下载过的图片
  • 缩略图生成
  • 检测图像的宽/高,确保它们满足最小限制

使用图片管道 

scrapy.pipelines.images.ImagesPipeline

 使用 ImagesPipeline ,典型的工作流程如下所示:

  • 1 在一个爬虫中,把图片的URL放入 image_urls 组内(image_urls是个列表)
  • 2 URL从爬虫内返回,进入图片管道
  • 3 当图片对象进入 ImagesPipeline,image_urls 组内的URLs将被Scrapy的调度器和下载器安排下载
  • 4 settings.py文件中配置保存图片路径参数 IMAGES_STORE
  • 5 开启管道

注意 需要安装pillow4.0.0以上版本 pip install pillow==9.2.0 

Scrapy 自定义ImagePipeline 

scrapy爬虫框架_第13张图片

问题

使用官方默认图片管道,有如下几个问题:

  • 文件名不友好
  • 存储图片URL的参数名称与类型太固定 

 解决方案 自定义ImagePipeline,扩展

  • 自定义图片管道
  • 继承 scrapy.pipelines.images import ImagesPipeline
  • 实现 get_media_requests(self, item, info) 方法
    • 发送请求,下载图片
    • 转发文件名
  • 实现 file_path(self,request,response=None,info=None,*,item=None)
    • 修改文件名与保存路径 

Scrapy 中settings配置 的使用 

scrapy爬虫框架_第14张图片

Scrapy允许自定义设置所有Scrapy组件的行为,包括核心、扩展、 管道和spider本身。

官网-参考配置

设置 — Scrapy 2.5.0 文档 (osgeo.cn)https://www.osgeo.cn/scrap y/topics/settings.html 

配置文档

BOT_NAME 默认: 'scrapybot' Scrapy项目实现的bot的名字。用来构造默认 User-Agent,同时 也用来log。 当你使用 startproject 命令创建项目时其也被自动赋值。

CONCURRENT_ITEMS 默认: 100 Item Processor(即 Item Pipeline) 同时处理(每个response 的)item的最大值

CONCURRENT_REQUESTS 默认: 16 Scrapy downloader 并发请求(concurrent requests)的最大 值。 

CONCURRENT_REQUESTS_PER_DOMAIN 默认: 8 对单个网站进行并发请求的最大值。 CONCURRENT_REQUESTS_PER_IP 默认: 0 对单个IP进行并发请求的最大值。如果非0,则忽略 CONCURRENT_REQUESTS_PER_DOMAIN 设定, 使用该设 定。 也就是说,并发限制将针对IP,而不是网站。 该设定也影响 DOWNLOAD_DELAY: 如果 CONCURRENT_REQUESTS_PER_IP 非0,下载延迟应用在IP而 不是网站上。 FEED_EXPORT_ENCODING ='utf-8' 设置导出时文件的编码

Scrapy 中 Request 的使用

scrapy爬虫框架_第15张图片

爬虫中请求与响应是最常见的操作,Request对象在爬虫程序中生 成并传递到下载器中,后者执行请求并返回一个Response对象

scrapy爬虫框架_第16张图片

 Request对象

class scrapy.http.Request(url[, callback,method='GET', headers, body, cookies, meta,encoding='utf-8', priority=0,dont_filter=False, errback])

一个Request对象表示一个HTTP请求,它通常是在爬虫生成,并由 下载执行,从而生成Response 参数

  • url(string) - 此请求的网址
  • callback(callable) - 将使用此请求的响应(一旦下载)作 为其第一个参数调用的函数。有关更多信息,请参阅下面的 将附加数据传递给回调函数。如果请求没有指定回调, parse()将使用spider的 方法。请注意,如果在处理期间引发 异常,则会调用errback。
  • method(string) - 此请求的HTTP方法。默认为'GET'。可 设置为"GET", "POST", "PUT"等,且保证字符串大写
  • meta(dict) - 属性的初始值Request.meta,在不同的请求之 间传递数据使用
  • body(str或unicode) - 请求体。如果unicode传递了,那 么它被编码为 str使用传递的编码(默认为utf-8)。如果 body没有给出,则存储一个空字符串。不管这个参数的类 型,存储的最终值将是一个str(不会是unicode或None)。
  • headers(dict) - 这个请求的头。dict值可以是字符串(对 于单值标头)或列表(对于多值标头)。如果 None作为值 传递,则不会发送HTTP头.一般不需要 encoding: 使用默认的 'utf-8' 就行 dont_filter:是否过滤重复的URL地址,默认为 False 过滤
  • cookie(dict或list) - 请求cookie。这些可以以两种形式发 送。

将附加数据传递给回调函数

请求的回调是当下载该请求的响应时将被调用的函数。将使用下载 的Response对象作为其第一个参数来调用回调函数 

def parse_page1(self, response):
    item = MyItem()
    item['main_url'] = response.url
    request = scrapy.Request("http://www.example.com/some_page.html",
                            
callback=self.parse_page2)
    request.meta['item'] = item
    return request
def parse_page2(self, response):
    item = response.meta['item']
    item['other_url'] = response.url
    return item

你可能感兴趣的:(python)