scrapy 框架入门

运行流程

官网:https://docs.scrapy.org/en/latest/intro/overview.html

流程图如下:

组件

1、引擎(EGINE):负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分;

2、调度器(SCHEDULER):用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址;

3、下载器(DOWLOADER):用于下载网页内容,并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的;

4、爬虫(SPIDERS):SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求;

5、项目管道(ITEM PIPLINES):在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作;

6、下载器中间件(Downloader Middlewares):位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,以及从DOWNLOADER传到EGINE的响应response,可用该中间件做以下几件事:

1、process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website); 2、change received response before passing it to a spider; 3、send a new Request instead of passing received response to a spider; 4、pass response to a spider without fetching a web page; 5、silently drop some requests. 7、爬虫中间件(Spider Middlewares):位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)

安装

# Linux平台
pip3 install scrapy

命令参数

# 查看帮助
scrapy -h
scrapy <command> -h


Global commands:    # 全局命令
    startproject    # 创建项目,会在当前目录下创建项目文件夹
    
    genspider       # cd 进入项目目录,创建爬虫程序
        scrapy genspider baidu_spider www.baidu.com
            # 就会在spider目录下生成 baidu_spider.py 文件
    
    settings        # 如果是在项目目录下,则得到的是该项目的配置
        > scrapy settings --get=SPIDER_MODULES
        ['first_crawl.spiders']

    runspider       # 运行一个独立的python文件,不必创建项目
        ROBOTSTXT_OBEY = False
        scrapy runspider  baidu_spider.py的绝对路径

    shell           # scrapy shell url地址  在交互式调试,如选择器规则正确与否
        scrapy shell https://www.baidu.com/
        # 进入交互环境后,可执行命令:
            response.text           # 文本内容
            response.body           # 二进制内容
            view(response)          # 打开浏览器查看响应页面,已下载到本地
            response.css('a')       # 查找所有a标签
            response.xpath('//a')   # 查找所有a标签
            quit()                  # 退出交互环境 

    fetch           # 独立于程单纯地爬取一个页面,可以拿到请求头
        scrapy fetch https://www.baidu.com/  # 直接获取所有信息,类似shell但没有交互调试
        
    view            # 下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求
        
    version         # scrapy version 查看scrapy的版本
    
    scrapy version  # -v查看scrapy依赖库的版本



Project-only commands:  # 必须切到项目文件夹下才能执行
    crawl           # 运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY=False
        scrapy crawl baidu_spider  # 此处爬虫名称为name属性对应的爬虫
    
    check           # 检测项目中有无语法错误
    
    list            # 列出项目中所包含的爬虫名
    
    parse           # scrapy parse url地址 --callback 回调函数,以此可以验证我们的回调函数是否正确
    
    bench           # scrapy bentch压力测试,检测每分钟能爬取的网页数


# 官网链接
    https://docs.scrapy.org/en/latest/topics/commands.html

项目结构

project_name/
   scrapy.cfg
   project_name/
       __init__.py
       items.py
       pipelines.py
       settings.py
       spiders/
           __init__.py
           爬虫1.py
           爬虫2.py
           爬虫3.py
  • 文件说明:
  1. scrapy.cfg:项目的主配置信息,用来部署scrapy时使用,爬虫相关的配置信息在·settings.py·文件中;
  2. items.py:设置数据存储模板,用于结构化数据,如:Django的Model;
  3. pipelines:数据处理行为,如:一般结构化的数据持久化
  4. settings.py:配置文件,如:递归的层数、并发数,延迟下载等。强调:配置文件的选项必须大写否则视为无效,正确写法USER_AGENT='xxxx';
  5. spiders:爬虫目录,如:创建文件,编写爬虫规则。

选择器xpath & css

测试网址:https://doc.scrapy.org/en/latest/_static/selectors-sample1.html 目标页面内容:

<html>
 <head>
  <base href='http://example.com/' />
  <title>Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
  </div>
 </body>
</html>

进入交互环境测试选择器使用:

scrapy shell https://doc.scrapy.org/en/latest/_static/selectors-sample1.html
# 进入交互环境
# response.selector.css()或.xpath返回的是selector对象,再调用extract()和extract_first()从selector对象中解析出内容。
获取标签对象 // & /

/仅限于子标签:

# 查找目标页面所有a标签下的img子标签
>>> response.xpath('//a/img').extract()
['<img src="image1_thumb.jpg">', '<img src="image2_thumb.jpg">', 
    '<img src="image3_thumb.jpg">', '<img src="image4_thumb.jpg">', '<img src="image5_thumb.jpg">']
    
    
>>> response.css('a img').extract()  # 返回对象列表


>>> response.css('a img').extract_first()  # 返回第一个标签对象
'<img src="image1_thumb.jpg">'

//在子孙标签中查找:

# 查找目标页面所有的div标签内容的所有img标签
>>> response.xpath('//div//img').extract()
['<img src="image1_thumb.jpg">', '<img src="image2_thumb.jpg">', '<img src="image3_thumb.jpg">', '<img src="image4_thumb.jpg">', '<img src="image5_thumb.jpg">']
获取标签中的文本text
>>> response.css('a::text').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']


>>> response.xpath('//div/a/text()').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 
    'Name: My image 4 ', 'Name: My image 5 ']
获取标签属性
# xpath获取a标签内的所有img的src属性
>>> response.xpath('//a//img/@src').extract()
['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']


## css获取属性
>>> response.css('img::attr(src)').extract()
['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']
嵌套查找
>>> response.xpath('//div').css('a').xpath('@href').extract_first()
'image1.html'
设置默认值
>>> response.xpath("//div[@id='asas']").extract_first(default='not found')
'not found'
按照属性查找
# 查找所有包含[href='image2.html']的标签
>>> response.xpath("//*[@href='image2.html']").extract_first()
'<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>'


>>> response.css('#images [href="image2.html"]').extract_first()
'<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>'
模糊匹配
>>> response.css('#images [href*="image2"]').extract_first()
'<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>'


>>> response.xpath('//a[contains(@href,"image1")]').extract_first()
'<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>'
>>> response.xpath('//*[contains(@href,"image1")]').extract_first()
'<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>'
正则表达式
# 先找到所有a标签的文本selecor对象,然后逐个用re进行匹配,直到找到匹配的
>>> response.xpath('//a').re(".*My image 1 ")[0]
'<a href="image1.html">Name: My image 1 '

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ELKstack简介及环境部署

    Logstash的运行依赖于Java运行环境, Logstash 1.5以上不低于java 7推荐使用最新版本的Java。由于只是运行Java程序,而不是开发,...

    程序员同行者
  • Kubernetes集群搭建之Master配置篇

    本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复【K8s实战】获取

    程序员同行者
  • Nagios监控平台搭建

    程序员同行者
  • Jtro的技术分享:三元表达式

    C#中有一个三元运算符“?:”,语法为:条件表达式?表达式1:表达式2; 该操作首先求出条件表达式的值(bool类型),为true时调用表达式1,为flase...

    LittleU
  • 从零开始用Python写一个聊天机器人(使用NLTK)

    我肯定你听说过 Duolingo :一款流行的语言学习应用,可以通过游戏来练习一门新语言。它因其新颖的外语教学方式而广受欢迎。其概念很简单:每天五到十分钟的互...

    AI研习社
  • 剑指offer 孩子们的游戏(圆圈中最后剩下的数)

    每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让...

    week
  • 死磕 java同步系列之AQS起篇

    AQS的全称是AbstractQueuedSynchronizer,它的定位是为Java中几乎所有的锁和同步器提供一个基础框架。

    彤哥
  • 7 整数反转

    假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

    木瓜煲鸡脚
  • Coreos 安装及配置

    Coreos 安装及配置 本文由Vikings(http://www.cnblogs.com/vikings-blog/) 原创,转载请标明.谢谢! 目前国内...

    随机来个数
  • LeetCode 866. 回文素数(除11外,偶数位的回文数都不是质数)

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/prime-palindrome 著作权归领扣网络所...

    Michael阿明

扫码关注云+社区

领取腾讯云代金券