前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >开启Scrapy爬虫之路

开启Scrapy爬虫之路

作者头像
诡途
发布于 2020-10-16 02:05:31
发布于 2020-10-16 02:05:31
76100
代码可运行
举报
文章被收录于专栏:诡途的python路诡途的python路
运行总次数:0
代码可运行

摘要

七夜大佬的《python爬虫开发与项目实战》,买了好多年了,学习了好多东西,基本上爬虫都是在这里面学的,后期的scrapy框架爬虫一直不得门而入,前段时间补了下面向对象的知识,今天突然顿悟了!写个笔记记录下学习过程

1.scrapy安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -i参数后跟清华镜像源,加速下载,其他pip的包也可这么操作
pip install Scrapy -ihttps://pypi.tuna.tsinghua.edu.cn/simple

测试如下图表示安装成功

其他参考方法:win7安装scrapy

2.相关命令介绍

scrapy命令分为

  • 全局命令:全局命令就是在哪都能用;
  • 项目命令:项目命令就是只能依托你的项目;

2.1全局命令

全局命令就是上图安装测试时主动跳出来的那些命令

startproject、genspider、settings、runspider、shell、fetch、view、version

比较常用的有三个:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scrapy startproject project_name # 创建项目
scrapy crawl spider_name # 运行名为spider_name的爬虫项目
# 调试网址为https://blog.csdn.net/qq_35866846的网站
scrapy shell "https://blog.csdn.net/qq_35866846"

全局命令就是不依托项目存在的,也就是不关你有木有项目都能运行, 比如:startproject它就是创建项目的命令,肯定是没有项目也能运行;

详细用法说明:

  • startproject # 使用频次最高,用于项目创建,eg:创建一个名为:cnblogSpider的项目 scrapy strartproject cnblogSpider
  • genspider # 用于创建爬虫模板,example是spider名称,生成文件在spiders下面,也是后面写爬虫的地方 # 注意spider名称不能和项目相同 scrapy genspider example example.com

详情请参考scrapy命令:scrapy genspider详解

  • settings # 查看scray参数设置 scrapy settings --get DOWNLOAD_DELAY # 查看爬虫的下载延迟 scrapy settings --get BOT_NAME # 爬虫的名字
  • runspider 运行蜘蛛除了使用前面所说的scrapy crawl XX之外,我们还能用:runspider; crawl是基于项目运行,runspide是基于文件运行, 也就是说你按照scrapy的蜘蛛格式编写了一个py文件,如果不想创建项目,就可以使用runspider,eg:编写了一个:test.py的蜘蛛,你要直接运行就是: scrapy runspider test.py
  • shell # 这个命令比较重要,主要是调试用,里面还有很多细节的命令 # 最简单常用的的就是调试,查看我们的选择器到底有木有正确选中某个元素 scrapy shell "https://www.cnblogs.com/qiyeboy/default.html?page=1" # 然后我们可以直接执行response命令, #比如我们要测试我们获取标题的选择器正不正确: response.css("title").extract_first() # 以及测试xpath路径选择是否正确 response.xpath("//*[@id='mainContent']/div/div/div[2]/a/span").extract()
  • fetch 这个命令其实也可以归结为调试命令的范畴!它的功效就是模拟我们的蜘蛛下载页面,也就是说用这个命令下载的页面就是我们蜘蛛运行时下载的页面,这样的好处就是能准确诊断出,我们的到的html结构到底是不是我们所看到的,然后能及时调整我们编写爬虫的策略!举个栗子,淘宝详情页,我们一般看得到,但你如果按常规的方法却爬不到,为神马?因为它使用了异步传输!因此但你发现获取不到内容的时候,你就要有所警觉,感觉用fetch命令来吧它的html代码拿下来看看,到底有木有我们想要的那个标签节点,如果木有的话,你就要明白我们需要使用js渲染之类的技术!用法很简单: scrapy fetch http://www.scrapyd.cn 就这样,如果你要把它下载的页面保存到一个html文件中进行分析,我们可以使用window或者linux的输出命令,这里演示window下如下如何把下载的页面保存: scrapy fetch http://www.scrapyd.cn >d:/3.html

可以看到,经过这个命令,scrapy下载的html文件已经被存储,接下来你就全文找找,看有木有那个节点,木有的话,毫无悬念,使用了异步加载!

  • view
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 和fetch类似都是查看spider看到的是否和你看到的一致,便于排错
scrapy view https://blog.csdn.net/qq_35866846
  • version
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 查看scrapy版本
scrapy version

2.2项目命令

项目命令比较简单,感觉没什么好说的,我也没怎么详细测试, 直接参考这篇【scrapy 命令行:scrpay项目命令】

3.scrapy框架介绍

Scrapy 是一个用python写的Crawler Framework,简单轻巧,并且十分方便,使用Twisted这个一部网络库来处理网络通信,架构清晰,并包含了各种中间件接口,可以灵活地完成各种需求,整体架构组成如下图

  • Scrapy引擎(Engine): 引擎负责控制数据流在系统的所有组件中流动,并在相应动作发生时触发事件;
  • 调度器(Scheduler): 调度器从引擎接收request 并将他们入队,以便之后引擎请求request时提供引擎;
  • 下载器(Downloader): 下载器负责获取页面数据并提供给引擎,而后提供给Spider;
  • Spider: Spider是Scrapy用户编写用于分析Response 并提取Item(即获取到的Item)或额外跟进的URL的类,每个Spider负责处理一个特定(或一些)网站
  • Item Pipeline: Item Pipeline 负责处理被Spider提取出来的Item .典型的处理有清理验证及持久化(例如存储到数据库中);
  • 下载器中间件(Downloader middlewares): 下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的Response。其提供了一个简单的机制,通过插入自定义代码来扩展Scrapy功能;
  • Spider中间件(Spider middlwares): Spider中间件是在引擎及Spider之间的特定钩子(specific hook), 处理Spider的输入(response)和输出(items 及request)其中提供了一个简便的机制,通过插入自定义代码来实现Scrapy功能。

4.Scrapy中数据流的流转

  1. 引擎打开一个网站(open a domain),找到处理该网站的Spider 并向该Spider请求第一个要爬取的URL
  2. 引擎从Spider中获取第一个要爬取的URL并通过调度器(Schedule)以Request进行调度
  3. 引擎向调度器请求下一个要爬取的URL
  4. 调度器返回下一个要爬取的URL给引擎,引擎降URL通过下载中间件(请求(request)方向)转发给下载器(Downloader)
  5. 一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方向)发送给引擎
  6. 引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理
  7. Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎
  8. 引擎将(Spider返回的)爬取到的Item 给Item Pipeline,将(Spider返回的)Request给调度器
  9. (从第二步)重复直到调度器中没有更多的Request,引擎关闭网站

5.第一个scrapy爬虫

七夜大佬《》的案例项目,由于书买的比较早,里面用的还是python2 自己动手在python3的环境下实现一下

5.1创建项目

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 创建一个名为cnblogSpider 的Scrapy项目
scrapy startproject cnblogSpider

创建好项目之后,直接使用pycharm打开,继续工作即可 结构性文件自动生成,把框架填充起来即可

  • scrapy.cfg: 项目部署文件
  • cnblogSpider/ : 给项目的python模块,之后可以在此加入代码
  • cnblogSpider/items.py:项目中的Item文件
  • cnblogSpider/pipelines.py:项目中的Pipelines文件
  • cnblogSpider/settings.py:项目的配置文件
  • cnblogSpider/spiders/:放置Spider代码的目录

5.2创建爬虫模块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from ..items import CnblogspiderItem
class CnblogsSpider(scrapy.Spider):
    name = "cnblogs"  # 爬虫的名称
    allowed_domains = ["cnblogs.com"]  # 允许的域名
    start_urls = [
        "https://www.cnblogs.com/qiyeboy/default.html?page=1"
    ]

    def parse(self, response):
        # 实现网页解析
        # 首先抽取所有文章
        papers = response.xpath("//*[@class='day']")
        # 从每篇文章中抽取数据
        for paper in papers:
            url = paper.xpath(".//*[@class='postTitle']/a/@href").extract()[0]
            title = paper.xpath(".//*[@class='postTitle']/a/span/text()").extract()[0]
            time = paper.xpath(".//*[@class='dayTitle']/a/text()").extract()[0]
            content = paper.xpath(".//*[@class='postCon']/div/text()").extract()[0]
            # print(url, title, time, content)
            item = CnblogspiderItem(url=url, title=title, time=time, content=content)
            yield item
        next_page = Selector(response).re(u'<a href="(\S*)">下一页</a>')
        if next_page:
            yield scrapy.Request(url=next_page[0], callback=self.parse)

5.3定义item

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class CnblogspiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    url = scrapy.Field()
    time = scrapy.Field()
    title = scrapy.Field()
    content = scrapy.Field()


class newCnblogsItem(CnblogspiderItem):
    body = scrapy.Field()
    # title = scrapy.Field(CnblogspiderItem.Fields['title'], serializer = my_serializer)

5.4构建Item Pipeline

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 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
import json
from scrapy.exceptions import DropItem
from .items import CnblogspiderItem


class CnblogspiderPipeline(object):
    def __init__(self):
        self.file = open('papers.json', 'w', encoding='UTF-8')

    def process_item(self, item, spider):
        if item['title']:
            line = json.dumps(dict(item)) + '\n'
            # print(type(line))
            # self.file.write(line.encode())
            # 注意open "wb" 写入的是字节流,“w”写入的是str
            # 使用decode 和 encode进行字节流和str的相互转化
            self.file.write(line)
            return item
        else:
            raise DropItem(f"Missing title in {item}")

5.5 激活Item Pipeline

定制完Item Pipeline ,它是无法工作的需要进行激活,要启用一个Item Pipeline组件 必须将它的类添加到settings.py中的ITEM_PIPELINES 变量中

自动创建的Scrapy直接把settings.py中的该行取消注释即可

TEM_PIPELINES 变量中可以配置很多个Item Pipeline组件,分配给每个类的整型值确定了他们的运行顺序,item 按数字从低到高的顺序通过Item Pipeline,取值范围0 ~1000

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ITEM_PIPELINES = {
   'cnblogSpider.pipelines.CnblogspiderPipeline': 300,
}

激活完成后,将命令行切换到项目目录下执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scrapy crawl cnblogs

参考资料

【1】书《python爬虫开发与项目实战》和 随书代码 【2】scrapy1.5中文文档

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/09/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Java基本数据类型、包装类及拆装箱详解
Java的基本数据类型和对应的包装类是Java语言中处理数据的两个关键概念。基本数据类型提供了简单而高效的方式来存储数据,而包装类使得基本数据类型具有对象的特性。本文将深入探讨基本数据类型与包装类的应用场景及详细描述,并对自动拆箱和装箱的源码实现进行分析。
修己xj
2023/12/05
6500
Java基本数据类型、包装类及拆装箱详解
Java学习【深入探索包装类和泛型】
在Java的学习中,包装类和泛型是两个重要的概念,它们不仅丰富了Java的数据类型,还提高了代码的可读性和安全性。下面,我们将深入探讨这两个主题。
2的n次方
2024/10/15
870
Java学习【深入探索包装类和泛型】
【Java】什么是泛型?什么是包装类
Java是一个面向对象的编程语言,但其基本数据类型(如int、char、boolean等)并不直接支持面向对象的特性。为了弥补这一不足,Java为每种基本数据类型设计了一个对应的类,这些类统称为包装类(Wrapper Class)。包装类均位于java.lang包中。
椰椰椰耶
2024/10/15
1380
【Java】什么是泛型?什么是包装类
包装类和泛型
在Java中,由于基本;类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。
用户11070251
2024/04/11
1320
【数据结构】包装类和泛型
除了int的包装类是Integer,char的包装类是Character,其他的基本类型对应的包装类都是将首字母大写。
用户11162265
2024/08/05
980
【数据结构】包装类和泛型
《JavaSE》---21.<简单认识Java的集合框架&包装类&泛型>
其主要表现为将多个元素 element 置于一个单元中,用于对这些元素进行快速、便捷的存储 store 、检索 retrieve 、 管理 manipulate ,即平时我们俗称的增删查改 CRUD 。
用户11288958
2024/09/24
1750
《JavaSE》---21.<简单认识Java的集合框架&包装类&泛型>
数据结构-1.初始包装类与泛型
在 Java 中,由于基本类型不是继承自 Object ,为了在泛型代码中可以支持基本类型, Java 给每个基本类型都对应了一个包装类型.
用户11369350
2024/11/19
600
知识改变命运——【数据结构】包装类&简单认识泛型
在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了 一个包装类型。
用户11319080
2024/10/17
720
知识改变命运——【数据结构】包装类&简单认识泛型
Java 泛型深入解析:类型安全与灵活性的平衡
Java 泛型(Generics)是一个强大的语言特性,它允许在类、接口和方法中使用参数化类型,从而实现代码的重用、增强类型安全性,并提升代码的可读性。泛型的引入解决了 Java 编程中常见的类型转换问题,使得我们能够编写更加灵活且健壮的代码。然而,泛型背后的类型擦除(Type Erasure)机制和一些高级特性也给我们带来了一定的挑战。
科技新语
2024/10/11
1790
Java 泛型深入解析:类型安全与灵活性的平衡
【数据结构】包装类&泛型
小编在这里设置了一个上界comparable,可以进行comparaTo方法的调用,当然改为整型也是可以的。 
用户11288949
2024/09/24
970
【数据结构】包装类&泛型
Java中的泛型(很细)
非常好,让我们深入探讨Java中的泛型这个重要主题。我将按照之前提供的框架,为您创作一篇全面而专业的技术博客文章。
程序员朱永胜
2024/07/18
2250
Java中的泛型(很细)
Java 中文官方教程 2022 版(六)
大多数情况下,如果您使用单个字符值,您将使用基本的char类型。然而,有时您需要将 char 用作对象—例如,作为期望对象的方法参数。Java 编程语言为此提供了一个包装类,将char包装在Character对象中。Character类型的对象包含一个类型为char的单个字段。这个Character类还提供了许多有用的类(即静态)方法来操作字符。
ApacheCN_飞龙
2024/05/24
2580
Java 中文官方教程 2022 版(六)
包装类与泛型,到底区别在哪?
在 Java 中,基本数据类型是不具有对象特性的,不支持面向对象的操作。但是,在某些情况下,我们需要将基本数据类型作为对象来操作,这时就需要使用包装类。
网络技术联盟站
2023/06/04
1910
Java 泛型:理解和应用
这就是泛型的概念,是 Java 后期的重大变化之一。泛型实现了参数化类型,可以适用于多种类型。泛型为 Java 的动态类型机制提供很好的补充,但是 Java 的泛型本质上是一种高级语法糖,也存在类型擦除导致的信息丢失等多种缺点,我们可以在本篇文章中深度探讨和分析。
phoenix.xiao
2023/08/28
2800
Java 泛型:理解和应用
Java泛型深入理解「建议收藏」
在面向对象编程语言中,多态算是一种泛化机制。例如,你可以将方法的参数类型设置为基类,那么该方法就可以接受从这个基类中导出的任何类作为参数,这样的方法将会更具有通用性。此外,如果将方法参数声明为接口,将会更加灵活。
全栈程序员站长
2022/09/10
8800
Java基础(十四):包装类
冬天vs不冷
2025/01/21
950
Java基础(十四):包装类
java基础之泛型
泛型 术语 "?"通配符 通配符的扩展 自定义泛型方法 "擦除"实例 类型参数的类型推断 自定义泛型类 泛型方法和泛型类的比较 泛型和反射 通过反射获得泛型的实际类型参数 本文对泛型的基本
xiangzhihong
2018/02/01
1.1K0
java基础之泛型
如何使用 Java 泛型来避免 ClassCastException
泛型是相关语言特性的集合,它允许类或方法对各种类型的对象进行操作,同时提供编译时类型安全性检查
Java宝典
2021/01/28
2.2K0
Java 比较器 和 包装类
Java Comparable接口强行对实现它的每个类的对象进行整体排序 这种排序被称为:自然排序
Java_慈祥
2024/08/06
1710
Java 比较器 和 包装类
Java包装类,基本的装箱与拆箱
将原始类型和包装类分开以保持简单。当需要一个适合像面向对象编程的类型时就需要包装类。当希望数据类型变得简单时就使用原始类型。
JanYork_简昀
2022/03/31
5260
Java包装类,基本的装箱与拆箱
相关推荐
Java基本数据类型、包装类及拆装箱详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验