Python进阶之Scrapy框架入门

1. Scrapy入门

1.1 什么是Scrapy

  • Scrapy是一个适用爬取网站数据、提取结构性数据的应用程序框架,它可以应用在广泛领域:Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。通常我们可以很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片。
  • Scrapy使用了Twisted异步网络框架,可以大大提高数据抓取的效率
    Twisted异步框架
    • 异步:调用在发出之后,这个调用就直接返回,不管有无结果
    • 非阻塞:关注的是程序在等待调用结果时的状态,指在不能立刻得到结果之前,该调用不会阻塞当前线程
    • 异步过程使得程序充分利用了阻塞等待的时间,使得程序在同样的时间可以干更多的事情,从而提高了执行效率

1.2 Scrapy架构

  • 一个标准的Scrapy架构由Scrapy Engine(引擎),Scheduler(调度器),Downloader(下载器),Spider(爬虫),Item Pipeline(管道),Downloader Middlewares(下载中间件),Spider Middlewares(Spider中间件)组成,如下图:
    Scrapy框架

  • Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。

  • Scheduler(调度器):它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。

  • Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理。

  • Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)。

  • Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方。

  • Downloader Middlewares(下载中间件):一个可以自定义扩展下载功能的组件。

  • Spider Middlewares(Spider中间件):一个可以自定扩展和操作引擎和Spider中间通信的功能组件。

1.3 安装Scrapy

2. Scrapy项目初探

2.1 创建一个Scrapy项目

  • 创建Scrapy项目,startproject后的项目名称可以按照需要指定

    scrapy startproject mySpider 
    

    运行后提示:
    You can start your first spider with:
    cd mySpider
    scrapy genspider example example.com

  • 创建爬虫,命令行运行cd mySpider进入爬虫目录后

    scrapy genspider demo "demo.cn"
    
    • demo为爬虫项目名称,在”./mySpider/spiders/“目录生成一个名为demo.py的文件
    • "demo.cn"为需要爬取的网站域名

    运行后提示:
    Created spider ‘demo’ using template ‘basic’ in module:
    mySpider.spiders.demo

  • 完善数据,完善爬虫项目数据,把爬虫代码添加到demo.py中

  • 保存数据,修改pipelines.py,把数据保存的代码添加到文件中

    • 1 可能会有多个spider,不同的pipeline处理不同的item的内容
    • 2 一个spider的内容可以要做不同的操作,比如存入不同的数据库中
      注意
      • pipeline的权重越小优先级越高
      • pipeline中process_item方法名不能修改为其他的名称

2.2 运行爬虫

  • 在命令中运行爬虫, # xxx是爬虫的名字,与爬虫项目名保持一致

    scrapy crawl XXX
    
  • 在pycharm中运行爬虫,

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

3. Scrapy抓取豆瓣数据实例

  • 通过一个抓取豆瓣的scrapy项目,简单介绍scrapy项目的开发逻辑

3.1 创建项目和爬虫

  • 创建scrapy项目

scrapy startproject spider

  • 进入项目目录

cd spider

  • 创建爬虫项目

scrapy genspider douban “douban.com”

3.2 douban.py

  • 注意:
  • parse中的response是一个可以使用xpath的对象,可以直接获取html数据
  • 利用Scrapy里边的extract_first()或get()取数据
    - get()获取有标签的数据
    - extract_first()获取文本数据,注意加(),否则会输出错误数据
    - bound method SelectorList.get of
  • 抓取结果保存成字典方便引用和保存
  • 返回数据用生成器形式yield返回,尽量不用return.这样可以节省内存资源
import scrapy
# from scrapy.http.response.html import HtmlResponse

class DoubanSpider(scrapy.Spider):
    name = 'douban'
    # 允许的域名范围,不需要加协议名
    allowed_domains = ['douban.com']
    # 可以修改
    start_urls = ['http://douban.com/']

    def parse(self, response):

        # print('-' * 50)
        # print(response)
        # print(type(response))
        # print('-' * 50)
        # response状态码200,说明已经抓到了html
        li_list = response.xpath('//div[@class="side-links nav-anon"]/ul//li')
        # 定义字典收集数据
        item = {}
        for li in li_list:

            # 利用Scrapy里边的extract_first()和get()取数据
            # get()获取有标签的数据
            # extract_first()获取文本数据,注意加(),否则会输出错
            # bound method SelectorList.get of

            # 发现输出缺少购书单,购书单在em标签下
            item['name'] = li.xpath('a/em/text()').extract_first()
            # 增加判断,如果找不到则执行下边的代码
            if item['name'] == None:
                # 其他标签都在a标签下
                item['name'] = li.xpath('a/text()').extract_first()
            # print(item)
            # 用yield生成器返回数据,节省内存资源
            yield item
        # print(li_list)

3.3 settings.py

  • 注意:
  • 设定LOG-LEVEL可以简化日志输出内容,调试时更为方便
  • 设定DEFAULT_REQUEST_HEADERS请求头
  • 根据实际需要确定ROBOTSTXT_OBEY = True是否要注释掉
  • 使用pipeline的时候要在settings里把# Configure item pipelines下边的ITEM_PIPELINES代码打开
BOT_NAME = 'spider'

SPIDER_MODULES = ['spider.spiders']
NEWSPIDER_MODULE = 'spider.spiders'
# 日志输出简化
LOG_LEVEL = 'WARNING'
# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3820.400 QQBrowser/10.6.4255.400',
  'Accept-Language': 'en',
}
# Obey robots.txt rules
# 注释掉了遵守robots协议
# ROBOTSTXT_OBEY = True

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'spider.pipelines.SpiderPipeline': 300,
   'spider.pipelines.SpiderPipeline1': 301,
}

3.4 pipeline.py

  • 注意:
  • 使用pipeline的时候要在settings里把# Configure item pipelines下边的ITEM_PIPELINES代码打开
  • ensure_ascii = False使json.dumps()处理支持为中文输出
# 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


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter

# 注意使用pipeline要在设置里边打开ITEM_PIPELINES setting
import json

class SpiderPipeline:

    def __init__(self):

        self.f = open('douban.json','w',encoding='utf-8')

    # 爬虫的打开方法
    def open_spider(self,item):
        print('爬虫开始了')

    def process_item(self, item, spider):
        # print(item)
        # json.dumps() 将字典形式数据转化成字符串 默认使用ascii编码
        # ensure_ascii = False 使item_json为中文形式
        # json.loads() 将字符串形式数据转化为字典
        # 把item字典数据转化为item_json字符串
        item['hello'] = 'world'
        item_json = json.dumps(item,ensure_ascii=False)
        self.f.write(item_json+'\n')
        return item

    # 爬虫关闭的方法
    def close_spider(self,item):
        print('爬虫结束了')
        self.f.close()

# 用第二个pipeline进行打印结果
# pipeline的优先级按照settings里的ITEM_PIPELINES中的数字大小顺序来定义优先级
class SpiderPipeline1:

    def process_item(self, item, spider):
        print(item)

3.5 start.py

  • 可以通过windows命令行输入scrapy crawl douban运行程序
  • 也可以调用scrapy中的cmdline.execute()创建python启动程序,注意后边有个.split()分隔
# !/usr/bin/python
# Filename: start.py
# Data    : 2020/08/25
# Author  : --king--
# ctrl+alt+L自动加空格格式化

from scrapy import cmdline

# cmdline.execute(['scrapy','crawl','douban'])
cmdline.execute('scrapy crawl douban'.split())

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingx3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值