首页 > 其他分享 >15--Scrapy01:介绍与初步使用

15--Scrapy01:介绍与初步使用

时间:2024-04-15 16:49:17浏览次数:38  
标签:15 -- py 爬虫 spider item scrapy data Scrapy01

Scrapy01--基本介绍与初步使用

一、爬虫工程化

何为工程化,就是让你的程序更加的有体系,有逻辑,更加的模块化.

到目前为止,我们所编写的爬虫我们都是从头到尾的每一步都要亲力亲为. 这样做固然有其优点(可控性更好),但是各位请认真思考.
这样的代码逻辑是不能形成批量生产的效果的(写100个爬虫). 很多具有共通性的代码逻辑都没有进行重复利用.
那我们就可以考虑看看,能不能把一些共性的问题(获取页面源代码,数据存储),单独搞成一个功能.
如果我们把这些功能单独进行编写. 并且产生类似单独的功能模块,将大大的提高我们爬虫的效率. 已达到我们爬虫工程化开发的效果.

爬虫工程化: 对爬虫的功能进行模块化的开发. 并达到可以批量生产的效果(不论是开发还是数据产出)

二、Scrapy简介

Scrapy到目前为止依然是这个星球上最流行的爬虫框架. 摘一下官方给出对scrapy的介绍

An open source and collaborative framework for extracting the data you need from websites.

In a fast,simple,yet extensible way.

scrapy的特点: 速度快,简单,可扩展性强

Scrapy的官方文档(英文): https://docs.scrapy.org/en/latest/

神马叫框架:按照框架本身设计的逻辑. 往里面填写内容就可以了

学习其他框架的时候. 切忌:不要去直接上来去抠它的源码

先学会如何使用(怎么往里填窟窿),再反着去看他的源代码. 理解起来就容易了

三、Scrapy工作流程(重点)

  • 之前爬虫的逻辑:

# 伪代码,只为说明
def get_page_srouce():
	resp = requests.get(xxxxx)
	return resp.text | resp.json()
	
def parse_source():
	xpath,bs4,re
    return data
	
def save_data(data):
	txt,csv,mysql,mongodb
	
def main():  # 负责掌控全局
    # 首页的页面源代码
	ret = get_page_source()  # 获取页面源代码,发送网络请求
	data = parse_source(ret)  # 去解析出你要的数据
	# 需要继续请求新的url
	while: 
		# 详情页 
		ret = get_page_source()  # 获取页面源代码,发送网络请求
		data = parse_source(ret)  # 去解析出你要的数据
		save_data(data) # 负责数据存储
        
        # 详情页如果还有分页.
        # ...继续上述操作. 
      
if __name__ == '__main__':
	main()
  • scrapy的工作流程:

scrapy整个工作流程

  1. 爬虫中起始的url构造成request对象,并传递给调度器
  2. 引擎调度器中获取到request对象,然后交给下载器
  3. 下载器来获取到页面源代码,并封装成response对象。并回馈给引擎
  4. 引擎将获取到的response对象传递给spider。由spider对数据进行解析(parse)。并回馈给引擎
  5. 引擎将数据传递给pipeline进行数据持久化保存或进一步的数据处理
  6. 在此期间,如果spider中提取到的并不是数据, 而是子页面url,可以进一步提交给调度器,进而重复步骤2的过程

# 伪代码,只为说明
def get_page_srouce(url,method):
    if method == get:
        resp = requests.get(xxxxx)
        return resp.text | resp.json()
	
def parse_source():
	xpath,bs4,re
	
def save_data(data):
	txt,csv,mysql,mongodb
	
def main():  # 负责掌控全局->为了你理解
	# 主页
    req = spider.get_first_req()
    while 1:
        scheduler.send(req)
        next = scheduler.next_req()
        sth = downloader.get_page_source(next)
        data = spider.parse(sth)
        if data is 数据:
        	pipeline.process_item(data)


if __name__ == '__main__':
	main()

上述过程中一直在重复着几个东西:5大组件

  1. 引擎(engine)

    scrapy的核心,所有模块的衔接,数据流程梳理.

  2. 调度器(scheduler)

    本质上这东西可以看成是一个集合和队列. 里面存放着一堆即将要发送的请求. 可以看成是一个url的容器. 它决定了下一步要去爬取哪一个url. 通常在这里可以对url进行去重操作.

  3. 下载器(downloader)

    它的本质就是用来发动请求的一个模块. 小白们完全可以把它理解成是一个requests.get()的功能. 只不过这货返回的是一个response对象.

  4. 爬虫(spider)

    这是我们要写的第一个部分的内容,负责解析下载器返回的response对象.从中提取到我们需要的数据.

  5. 管道(pipeline)

    这是我们要写的第二个部分的内容,主要负责数据的存储和各种持久化操作.

经过上述的介绍来看,scrapy其实就是把平时写的爬虫进行了四分五裂式的改造. 对每个功能进行了单独的封装,并且,各个模块之间互相的不做依赖. 一切都由引擎进行调配。

这种思想希望你能知道:解耦. 让模块与模块之间的关联性更加的松散.

这样我们如果希望替换某一模块的时候会非常的容易. 对其他模块也不会产生任何的影响.

到目前为止,我们对scrapy暂时了解这么多就够了. 后面会继续在这个图上进一步展开.

四、Scrapy安装

在windows上安装scrapy,可能会出现各种各样的异常BUG.

4.1 正常安装

### scrapy 2.5.1  --->  scrapy-redis 0.7.2

注意:由于scrapy的升级. 导致scrapy-redis无法正常使用
所以选择2.5.1这个版本作为学习. 后期各位可以根据scrapy-redis的升级,而跟着升级scrapy


# 先使用pip直接安装,看看报错不
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scrapy==2.5.1 
pip install scrapy==2.5.1


如果安装成功,直接去创建项目即可
如果安装失败,请先升级一下pip,然后重新安装scrapy即可.
最新版本的pip升级完成后. 安装依然失败,可以根据报错信息进行一点点的调整,多试几次pip. 直至success

4.2 安装包安装

如果上述过程还是无法正常安装scrapy,可以考虑用下面的方案来安装:

# 1.安装wheel
pip install wheel

# 2.下载twisted安装包,https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

# 3.用wheel安装twisted
pip install Twisted‑21.7.0‑py3‑none‑any.whl

# 4.安装pywin32
pip install pywin32

# 5.安装scrapy
pip install scrapy

# 最终控制台输入 scrapy version 能显示版本号. 就算成功了

4.3 调整OpenSSL版本

安装完成后. 请调整OpenSSL的版本

输入命令: scrapy version --verbose

### 错误版本:

Scrapy       : 2.5.1
lxml         : 4.9.0.0
libxml2      : 2.9.12
cssselect    : 1.1.0
parsel       : 1.6.0
w3lib        : 1.22.0
Twisted      : 22.4.0
Python       : 3.9.12 (tags/v3.9.12:b28265d,Mar 23 2022,23:52:46) [MSC v.1929 64 bit (AMD64)]
pyOpenSSL    : 22.0.0 (OpenSSL 3.0.4 21 Jun 2022)  # 此时用的是3.0.4  要降低它的版本
cryptography : 37.0.3
Platform     : Windows-10-10.0.19043-SP0

更改方案:

pip uninstall cryptography

pip install cryptography==36.0.2

再次输入 scrapy version --verbose

### 正确版本:

Scrapy       : 2.5.1
lxml         : 4.9.0.0
libxml2      : 2.9.12
cssselect    : 1.1.0
parsel       : 1.6.0
w3lib        : 1.22.0
Twisted      : 22.4.0
Python       : 3.9.12 (tags/v3.9.12:b28265d,Mar 23 2022,23:52:46) [MSC v.1929 64 bit (AMD64)]
pyOpenSSL    : 22.0.0 (OpenSSL 1.1.1n  15 Mar 2022)  # 正确
cryptography : 36.0.2
Platform     : Windows-10-10.0.19043-SP0

五、Scrapy实例

接下来,用scrapy来完成一个超级简单的爬虫,目标: 深入理解Scrapy工作的流程,以及各个模块之间是如何搭配工作的.

5.1 创建项目

scrapy startproject 项目名称


# eg:
scrapy startproject mySpider_2

创建好项目后,在pycharm里观察到scrapy创建了一个文件夹,里面的目录结构如下:

mySpider_2   # 项目所在文件夹,建议用pycharm打开该文件夹
    ├── mySpider_2  		# 项目根目录
    │   ├── __init__.py
    │   ├── items.py  		# 封装数据的格式   一个一个的类,相当于models.py
    │   ├── middlewares.py  # 所有中间件
    │   ├── pipelines.py	# 所有的管道   持久化相关写在这(items.py中类的对象)
    │   ├── settings.py		# 爬虫配置信息
    │   └── spiders			# 爬虫文件夹,稍后里面会写入爬虫代码
    │       └── __init__.py
    └── scrapy.cfg			# scrapy项目配置信息  上线部署相关  别动它 

5.2 创建爬虫

cd 文件夹  # 进入项目所在文件夹

scrapy genspider 爬虫名称 允许抓取的域名范围

# eg:
cd mySpider_2

scrapy genspider youxi 4399.com

至此,爬虫创建完毕,打开文件夹看一下.

├── mySpider_2
│   ├── __init__.py
│   ├── items.py
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       ├── __init__.py
│       └── youxi.py   # 多了一个这个
|
└── scrapy.cfg

5.3 编写数据解析过程

主要就是编写 spiders 中爬虫的 parse()方法

# 完善youxi.py中的内容

import scrapy

class YouxiSpider(scrapy.Spider):
    name = 'youxi'  # 该名字非常关键,在启动该爬虫的时候,需要这个名字
    allowed_domains = ['4399.com']  # 爬虫抓取的域.
    start_urls = ['http://www.4399.com/flash/']  # 起始页

    def parse(self,response,**kwargs):
        # response.text     # 页面源代码
        # response.json()   # 提取json数据
        
        # response.xpath()  # 通过xpath方式提取
        # response.css()    # 通过css方式提取
            # 返回的是selector对象(标签元素),若需要提取内容
              .extract_first()  # 取一个  返回是字符串
              .extract()        # 取所有  返回是列表形式  
 

        # 用最熟悉的方式: xpath提取游戏名称,游戏类别,发布时间等信息
        li_list = response.xpath("//ul[@class='n-game cf']/li")
        for li in li_list:
            name = li.xpath("./a/b/text()").extract_first()
            category = li.xpath("./em/a/text()").extract_first()
            date = li.xpath("./em/text()").extract_first()

            dic = {
                "name": name,
                "category": category,
                "date": date
            }

            # 将提取到的数据提交到管道内.
            # 注意,这里只能返回 request对象,字典,item数据,or None
            yield dic
            
            
### 注意:   通常就是 借助item对象 来进行将数据 传输到管道中,进而持久化保存
spider返回的内容只能是字典、requestes对象、item数据、None ,其他内容一律报错

5.4 编写持久化

主要就是 编写数据的存储 涉及文件 items.py 和 pipelines.py

首先修改settings.py文件中的pipeline信息

ITEM_PIPELINES = {
    # 前面是pipeline的类名地址  后面是优先级,优先级越低,越先执行
   'mySpider_2.pipelines.Myspider2Pipeline': 300,
    
    # 指定pipline,可以指定多个  保存到多个位置 (文件、数据库等)
    
}

简单修改一下pipeline中的代码:

class Myspider2Pipeline:
    # 这个方法的声明不能动!!! 在spider返回的数据,会自动的调用这里的process_item方法.
    def process_item(self,item,spider):
        # 真正存储的地方
        print(item)
        return item   # 一定不要忘了return item,交给后续的pipline继续使用

5.5 运行爬虫

scrapy crawl 爬虫名字

# eg:
scrapy crawl youxi

六、自定义数据传输结构item

在上述案例中,使用字典作为数据传递的载体,但是如果数据量非常大. 由于字典的key是随意创建的. 极易出现问题

Scrapy中提供item,作为数据格式的声明位置.

可以在items.py文件提前定义好,该爬虫在进行数据传输时的数据格式,然后再写代码的时候,就有了数据名称的依据了.

  • item.py文件
import scrapy

class GameItem(scrapy.Item):
    # 定义数据结构
    name = scrapy.Field()
    category = scrapy.Field()
    date = scrapy.Field()
    
class Person:
    private String name;
    private int age;
    
    
dic = {name: "alex",age: 18}

p = Person( "alex",18)
  • spiders下的youxi.py
from mySpider_2.items import GameItem

# 以下代码在spider中的parse替换掉原来的字典
item = GameItem()

# 封装数据 到 item中
item["name"] = name
item["category"] = category
item["date"] = date

yield item
  • pipelines.py
class Myspider2Pipeline:
   
    def process_item(self,item,spider):
        # 真正存储的地方
        print(item)   # 从item中取出数据,进行持久化存储
        
        return item   # 一定不要忘了return item,交给后续的pipline继续使用

七、scrapy使用小总结

至此,我们对scrapy有了一个非常初步的了解和使用. 快速总结一下scrapy框架的使用流程:

  1. 创建爬虫项目. scrapy startproject 项目名

  2. 进入项目目录. cd 项目名

  3. 创建爬虫 scrapy genspider 爬虫名 抓取网站的域名

  4. 编写item.py 文件,定义好数据传输类 item

  5. 调整spider

    修改spider中的parse方法,对返回的响应response对象进行解析, 返回item

  6. 在pipeline中对数据进行保存工作.

  7. 调整settings配置文件

    将pipeline设置为生效,并设置好优先级

    干掉robots协议
    干掉日志的信息(想留下有用的内容), 只需要调整日志记录级别
    LOG_LEVEL = "WARNING"

  8. 启动爬虫 scrapy crawl 爬虫名

标签:15,--,py,爬虫,spider,item,scrapy,data,Scrapy01
From: https://www.cnblogs.com/Edmondhui/p/18136312

相关文章

  • trino与GBase8c的交互使用
    trino与GBase8c的交互使用trinoGBase8c迁移跨库查询支持GBase8c与其他数据库(oracle、mysql、postgresql、sqlserver等)之间进行跨库查询、连接查询、表及数据的迁移Trino参考文档:https://trino.io/docs/current/1、工具下载trinoserver/trinoclient:https://trino.io/d......
  • MySQL锁、事务和索引
    并发事务的控制方式是MVCC和行锁按范围分:表级锁、页锁、行级锁(锁一行或者多行)(记录索、间隙锁、临键锁(可重复读默认用这个做行锁,除非是主键和唯一索引会使用记录索))按功能分:读锁(S)、写锁(X)意向锁是表级锁,分为意向共享锁、意向排他锁,用于协调表锁和行锁的关系,事务想要在某些行上加共......
  • Canvas图形编辑器-数据结构与History(undo/redo)
    Canvas图形编辑器-数据结构与History(undo/redo)这是作为社区老给我推Canvas,于是我也学习Canvas做了个简历编辑器的后续内容,主要是介绍了对数据结构的设计以及History能力的实现。在线编辑:https://windrunnermax.github.io/CanvasEditor开源地址:https://github.com/Wind......
  • 一款功能齐全的iOS混淆工具介绍及功能详解
    ​机缘巧合偶遇iOS马甲包业务,前期也使用过目前市面上其他得工具,实际效果不太理想。经过大量实践,开发出一款功能齐全的混淆工具。工具的主要功能OC、C++、Swift已封装成Mac应用,其他功能还在封装中,敬请期待。马甲包的本质:阶段一减低重复率,本人开发初期的版本和目前市面上的其......
  • 01、BGP基本概念
    BGP的基本概念本章节介绍了BGP的基本概念,理解这些基本概念后,您可以更好的理解BGP的其它功能。自治系统AS(AutonomousSystem)AS是指在一个实体管辖下的拥有相同选路策略的IP网络。BGP网络中的每个AS都被分配一个唯一的AS号,用于区分不同的AS。AS号分为2字节AS号和4字节AS号,其中......
  • 用k8s的networkpolicy模拟租户隔离、组间pod隔离
    pod之间的通信默认是不隔离的,他们之是能相互通信的,但如果你想通过IP地址或者端口来管理网络通信,那么就可以使用k8s的networkpolicy功能。该功能的实现原理是默认都不通过,显示添加白名单。如果指定namespace,那么该networkpolicy生效的范围是本namespace内。如果没有指定namespace,......
  • 实验一——母婴购物App
    一、分析墨刀、Axure、Mockplus原型设计工具的各自的适用领域及优缺点(一)墨刀适用领域:适用于中小型项目的快速原型设计,尤其适合移动应用设计,需要云端操作和网页分享的场景。优点:1.用户界面简单易用,易上手,支持多人协作,可同时完成一份文件。2.交互制作功能强大,支持多种手势和转......
  • 02、BGP工作原理
    BGP工作原理BGP对等体的建立、更新和删除等交互过程主要有5种报文、6种状态机和5个原则。BGP的报文BGP对等体间通过以下5种报文进行交互,其中Keepalive报文为周期性发送,其余报文为触发式发送:Open报文:用于建立BGP对等体连接。Update报文:用于在对等体之间交换路由信息。......
  • @Degenerate_Sheep
    因为神秘原因翻到了之前的一个......
  • 扩展中国剩余定理证明及例题 Strange Way to Express Integers
    前置知识中国剩余定理(CRT),逆元;EXCRT是什么我们知道,对于对于\[\begin{equation} \begin{cases} x\equivc_1\(mod\m_1)\\ x\equivc_2\(mod\m_2)\\ .\\ .\\ .\\ x\equivc_i\(mod\\m_i)\\ \end{cases}\end{equation}\]一个一元线性......