首页 > 其他分享 >scrapy框架学习笔记

scrapy框架学习笔记

时间:2024-10-11 19:34:15浏览次数:7  
标签:pipeline 框架 item url Request 笔记 Item scrapy

scrapy运行机制

详见Architecture overview

安装

直接pip install scrapy即可

使用

命令行

  • scrapy startproject name命令创建一个新的Scrapy项目
  • scrapy crawl SpiderName命令运行爬虫
  • scrapy runspider SpiderName命令运行脚本。
    更多命令直接查Command line tool

概述

  • 编写Spider,返回Request或自定义的Item对象
  • 所有Request对象都会被scrapy调度请求,并在请求后调用设定的callback函数
  • Item对象则是提取请求回的数据,结构化数据并交由item pipeline处理
  • 定义好Item对象,存储必要的信息(个人认为以文本数据为主,二进制数据应保存链接后续pipeline处理)
  • 定义item pipeline,处理Item对象,例如存储到数据库或文件

编写Spider

  1. project/spider下创建Spider文件(scrapy genspider SpiderName website.com可快速创建示例)
    定义Spider类,必须继承scrapy.Spider类,并且必须指定类参数namescrapy crawl通过这个name来启动爬虫。

  2. 实现start_requests方法,定义爬虫入口,返回一个Request对象。
    如果只是简单的get请求,可以设定类参数start_urls = [url list]以使用默认方法(默认回调是parse方法)

  3. 实现parse(self, response)方法,用于处理请求返回的响应,返回Item对象或者Request对象。
    经常有请求完初始链接后要从响应拿到下一步的链接,这时可以在parse方法中返回一个Request对象,callback指定另一个函数,且可以通过kw_args传递额外参数(如本次处理的数据)给callback。
    返回Item则会交给pipeline处理

  4. Request对象和Response对象Selectors

from scrapy.http import Request, JsonRequest
...
# 一般的Request请求构建
yield Request(
    url=url,
    method="GET",           # 默认get,一般不写
    headers={},             # 看需要写,Spider middleware好像也能操作
    callback=self.parse,    # 自定义回调函数
    cb_kwargs={"additional_args": args},
)
# post请求
yield Request(
    url=url,
    method="POST",
    headers={"Content-Type": "application/json"},  # 看需要写
    callback=self.parse,
    body=json.dumps(payload),   # 注意转成JSON字符串
)
yield JsonRequest(  # 省略content-type,基本就是post请求
    url=url,
    data=payload,  # 注意这个直接传dict
    callback=self.parse,
)
def parse(self, response, if_additional_args):
    response.text
    response.body   # 取二进制数据,注意不是requests的content
    response.json() # 如果是json数据,可以直接使用

    # scrapy可以直接使用xpath和css选择器,非常方便
    for quote in response.xpath("//div[@class='quote']"):  # 返回的是SelectorList对象,可以遍历
        yield {
            "quote": quote.xpath("./span[1]/text()").get(),         # 注意用get返回第一个结果值
            "author": quote.xpath("span[2]/small/text()").get(), 
            "tags": quote.css("a.tag::text").getall(),              # 注意用getall返回所有结果的列表
        }

定义Item

project/item下定义Item类
Item类必须继承scrapy.Item类,Item其实就是个字典,但是key只能是定义了的字段名

class CspProblemItem(scrapy.Item):
    # contest info
    contest_id = scrapy.Field()
    contest_title = scrapy.Field()
    contest_date = scrapy.Field()

    # problem info
    title = scrapy.Field()
    description_url = scrapy.Field()
    description_filepath = scrapy.Field()
    description = scrapy.Field()
    attachment_urls = scrapy.Field()        # 最后下载的文件一般不保存在Item字段里,
    attachment_filepaths = scrapy.Field()   # 而是记录文件的url和路径,保存后记录在Item里

    # flags to indicate whether the problem has been processed
    done = scrapy.Field()

编写pipeline

  • project/pipeline下定义pipeline类,不需继承,要实现process_item(self, item, spider)方法
  • 启用pipeline需要在settings.py中设置ITEM_PIPELINES,将需要的pipeline类加上,并赋上priority(越小优先级越高)
  • 每个pipeline都必须返回自己处理的item,item之后会流经其它pipeline
  • pipeline处理处理Item时,该Item就会被锁定该pipeline中直到被return
  • 对于不需要的Item对象可以丢弃,通过raise DropItem("drop item info")丢弃
  • item在这里其实是鸭子类型,scrapy提供了ItemAdapter来统一它们
# 因为Item是鸭子类型,在使用时需要判断类型和字段
from itemadapter import ItemAdapter
class MyPipeline:
    def process_item(self, item, spider):
        adapter = ItemAdapter(item)
        adapter = ItemAdapter(item)
        adapter.get("key")              # 其实和dict.get()是一样的
        adapter.is_item_class(MyItem)   # 用于判断是否是需要的Item类型
        if adapter.get("done"):         # 对于非目标对象,要把Item返回
            return item
  • 有时需要下载item里的url,直接使用response的返回值,使用callback就很不方便,这时就要用到deferred
# https://docs.scrapy.org/en/latest/topics/coroutines.html#inline-requests
from itemadapter import ItemAdapter
from scrapy.exceptions import DropItem

from scrapy import Request
from scrapy.http.request import NO_CALLBACK
from scrapy.utils.defer import maybe_deferred_to_future
from twisted.internet.defer import DeferredList

class MyPipeline:
    async def process_item(self, item, spider):  # 注意要使用async
        adapter = ItemAdapter(item)

        # 单个请求
        request = Request(adapter["url"], callback=NO_CALLBACK)  # 不使用callback
        response = await maybe_deferred_to_future(
            spider.crawler.engine.download(request)
        )
        if response.status != 200:  # 一般要判断一下下载是否成功,并做一些处理
            raise DropItem(f"Could not download {adapter['url']}")
        
        # 多个请求,就是比单个的多了DeferredList包装
        deferred_list = []
        for url in url_list_:
            request = Request(url, callback=NO_CALLBACK)
            deferred = spider.crawler.engine.download(request)
            deferred_list.append(deferred)
        result = await maybe_deferred_to_future(DeferredList(deferred_list))

        # result变量将包含一个列表,该列表中的每个元素是一个元组,表示每个Deferred的结果。这个元组通常有两种形式:
        # (True, result):如果对应的Deferred成功完成,result是回调链最终返回的结果。
        # (False, failure):如果对应的Deferred因错误而终止,failure是一个Failure实例,代表发生的异常。
        for i, (success, response) in enumerate(result):
            if not success:
                continue
            file_path.write_bytes(response.body)

关于settings.py

  • 如果全局使用固定的cookie(在浏览器复制),需要在settings.py中注释修改DEFAULT_REQUEST_HEADERS,并且将COOKIES_ENABLED设置为False,否则这里的headers不能使用到cookie。或者也可以在middleware中进行自定义
  • 在settings可以定义自己需要的任何参数,使用Spider对象的spider.settings["key"]即可取到参数值

That's all

其实还有middleware等可以定制更丰富的功能,这些都可以直接查询官方文档,根据自己需要进行定制

标签:pipeline,框架,item,url,Request,笔记,Item,scrapy
From: https://www.cnblogs.com/faf4r/p/18459114

相关文章

  • Prompt 学习地图 | 框架思维
    该框架主要包括以下五个部分:背景B(Background)角色R(Role)目标O(Objectives)关键结果K(KeyResults)实验改进E(Evolve)框架解释背景(Background)背景信息部分提供关于请求的背景和上下文,它帮助ChatGPT更好地理解问题的背后意图和情境。例如,当你询问有关......
  • C语言笔记 13
    初见函数求素数的和#include<stdio.h>intmain(){intm,n;intsum=0;intcnt=0;inti;scanf("%d%d",&m,&n);//m=10,n=31;if(m==1)m=2;for(i=m;i<=n;i++){intisPrime=1;intk;for(k=2;......
  • Axure重要元件二——内联框架
    亲爱的小伙伴,在您观看之前,烦请您关注一下,在此深表感谢!本节课:内联框架课程内容:认识内联框架、基本嵌入应用场景:表单、图片、文字嵌入式场景、交互应用一、认识内联框架内联框架的基本功能和其他icon一样具有剪切、复制、粘贴等功能;独特的功能是可以通过框架目标去嵌入原型......
  • 笔记本电脑蓝屏固态硬盘数据恢复
    当笔记本电脑出现蓝屏故障,并且需要恢复固态硬盘中的数据时,可以参考以下步骤和建议:一、初步处理与评估断开电源:在尝试任何数据恢复操作之前,首先要断开笔记本电脑的电源,以避免进一步的数据损坏或丢失。评估蓝屏原因:蓝屏可能是由多种原因引起的,如驱动程序错误、系统文件损坏、硬件......
  • 数据资产 学习笔记(零)核心概念收录
    1、数据在常见的DIKW层次结构模型中,数据(Data)被视为一系列原始素材和原始资料,经由处理后形成有逻辑的信息(Information),人们通过组织化的信息分析出原因和机制,形成知识(Knowledge)再通过不断地应用与验证,逐渐形成智慧(Wisdom),并由此达成预测未来的可能。2、数据资产......
  • 使用Bootload升级相关的开发笔记
    项目使用两款不同的芯片完成Boot到APP之间的升级,此处仅作为日常开发笔记。(作者忘性大)1.GD32F403相关的boot升级 要实现boot升级主要分为IAP和APP两部分程序。IAP实际就是Boot相关的配置。①首先创建一个工程,将GD32F403原先的flash改为0x4000大小(16K)。此时已经将IAP的......
  • express的使用笔记 2 请求对象与响应对象 、 增删改查demo
    Express不对Node.js已有的特性进行二次抽象,只是在它之上扩展了web应用所需的基本功能。内部使用的依旧是http模块,请求对象继承字http.IncomingMessage,响应对象继承自http.ServerResponse,所以node.js官网中的对应的方法可以通用1.请求对象2.响应对象除了response.send(),resp......
  • 【刷题笔记】DP 2021.10.11
    Candies思路朴素的算法设\(f_{i,j}\)表示给前\(i\)个小朋友分\(j\)个糖的方案数,\[f_{i,j}=\sum_{k=0}^{min(a[i],j)}f_{i-1,j-k}\]注意到此时时间复杂度为\(O(n\timesk^2)\)想到用前缀和进行优化,设\(s_{i,j}\)表示\(\sum_{j=0}^{k}f_{i,j}\)则\(DP\)转移方程\[f_{i,j}=s_......
  • 【刷题笔记】[ABC180F] Unbranched
    【刷题笔记】Unbranched题意求\(N\)个点,\(M\)条边且满足以下条件的图的数量:1.图中无自环;2.每个点度数最多为2;3.连通块大小的最大值恰好为L。答案对\(10^9+7\)取模。\(1\leM,L\leN,2\leN\le300\)思路注意构造出来的图,不一定是联通的,所以容易联想到将一个联通分量......
  • ui自动化测试框架po框架
    一、po基本介绍(1)PO框架是Page Object的缩写(2)po框架:业务流程与页面元素操作分离的模式,可以简单理解为每个页面下面都有一个配置class, 配置class就用来维护页面元素或操作方法(3)提高测试用例的可维护性、可读取性(4)对比:传统的设计测试用例存在的弊端:1.易读性差2.复用性差3.可维护性......