爬虫——scrapy的基本使用

一,scrapy的概念和流程

1. scrapy的概念

Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架。

框架就是把之前简单的操作抽象成一套系统,这样我们在使用框架的时候,它会自动的帮我们完成很多工作,我们只需要完成剩余部分

Scrapy 使用了Twisted['twɪstɪd]异步网络框架,可以加快我们的下载速度。
Scrapy文档地址:http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/overview.html

2. scrapy框架的作用

少量的代码,就能够快速的抓取 ,框架是代码的半成品,提高效率(爬虫效率和开发效率

3. scrapy的工作流程

  1. 爬虫中起始的url构造成request对象-->爬虫中间件-->引擎-->调度器
  2. 调度器把request-->引擎-->下载中间件--->下载器
  3. 下载器发送请求,获取response响应---->下载中间件---->引擎--->爬虫中间件--->爬虫
  4. 爬虫提取url地址,组装成request对象---->爬虫中间件--->引擎--->调度器,重复步骤2
  5. 爬虫提取数据--->引擎--->管道处理和保存数据

4.scrapy中每个模块的具体作用

引擎(engine):负责数据和信号在不同模块间的传递

调度器(scheduler):实现一个队列,存放引擎发过来的request请求对象

下载器(downloader):发送引擎发过来的request请求,获取响应,并将响应交给引擎

爬虫(spider):处理引擎发过来的response,提取数据,提取url,并交给引擎

管道(pipeline):处理引擎传递过来的数据,比如存储

下载中间件(downloader middleware):可以自定义的下载扩展,比如设置代理ip

爬虫中间件(spider middleware):可以自定义request请求和进行response过滤,与下载中间件作用重复

注意:

爬虫中间件和下载中间件只是运行逻辑的位置不同,作用是重复的:如替换UA等

二、scrapy的入门使用

1.安装scrapy

1.windonws/Mac安装命令:

pip/pip3 install scrapy

(换源安装命令:pip install scrapy -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.comn )

2.安装依赖包:

pip install pypiwin32

如果不安装,以后的项目会报错,window系统需要安装,Linux,Mac不需要

2.scrapy项目开发流程

  1. 创建项目:
        scrapy startproject mySpider
  2. 生成一个爬虫:
        scrapy genspider lianjia lianjia.com
  3. 提取数据:
        根据网站结构在spider中实现数据采集相关内容
  4. 保存数据:
        使用pipeline进行数据后续处理和保存

3. 创建项目

通过命令将scrapy项目的的文件生成出来,后续步骤都是在项目文件中进行相关操作,下面以抓取链家来学习scrapy的入门使用
创建scrapy项目的命令:

scrapy startproject <项目名字>

示例:

scrapy startproject myspider

4. 创建爬虫

通过命令创建出爬虫文件,爬虫文件为主要的代码文件,通常一个网站的爬取动作都会在爬虫文件中进行编写。

命令:

在项目路径下执行:

scrapy genspider <爬虫名字> <允许爬取的域名>

爬虫名字 : 作为爬虫运行时的参数
允许爬取的域名: 为对于爬虫设置的爬取范围,设置之后用于过滤要爬取的url,如果爬取的url与允许的域不通则被过滤掉。

示例:

cd myspider 这一步是进入当前项目路径

scrapy genspider lianjia lianjia.com 再创建爬虫文件

以上操作完成后再打开pycharm就可以清楚查看到项目层级结构

现对如下几个py文件做说明:

1.scrapy.cfg 详细项目配置文件, 不需要做改动

2.items.py 定义数据存储模型

# Define here the models for your scraped items

# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy

# 实际是一个模板类  主要是用来定义数据存储模型
# 通过这个类实例化 数据实际存到实例(对象)中
class MyspiderItem(scrapy.Item):
    # 实际是一个模板类(数据建模) 事先定义好你要爬取的字段
    name = scrapy.Field()  # 租房标题
    content = scrapy.Field() # 详情信息
    price = scrapy.Field()  # 价格
    link = scrapy.Field() # 详情链接

3.middlewares.py 用于编写中间件(下载中间件+爬虫中间件) -- 无特殊需求,一般不需要编写

4.lianjia.py (爬虫文件,文件名称自己定义) [后面再来完善该爬虫模块]

import scrapy

class LianjiaSpider(scrapy.Spider):
    # 爬虫名字
    name = 'lianjia'
    # 限定爬取的域名范围
    allowed_domains = ['cs.lianjia.com']
    # 起始请求的URL
    start_urls = ['https://cs.lianjia.com/zufang/']
    
    # 该方法会接受下载中间件传过来的response,并对其进行解析
    def parse(self, response):
        pass

5.pipelines.py 管道 -- 主要用于编写数据处理步骤 (数据的清洗+保存)

# 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

class MyspiderPipeline:
    def process_item(self, itemder):
        return item

6.settings.py 详细的配置信息(设置文件UA 并启动管道)

# Scrapy settings for mySpider project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.html

BOT_NAME = 'mySpider'

SPIDER_MODULES = ['mySpider.spiders']
NEWSPIDER_MODULE = 'mySpider.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
# 需要手动修改成自己浏览器的UA
USER_AGENT = 'mySpider (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False # 需要手动修改为False

# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
#COOKIES_ENABLED = False

# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False

# Override the default request headers:
# 可以写入一些爬虫所需要的身份信息
#DEFAULT_REQUEST_HEADERS = {
#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
#   'Accept-Language': 'en',
#}

# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
# SPIDER_MIDDLEWARES = {
#    'mySpider.middlewares.MyspiderSpiderMiddleware': 543,
# }

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    'mySpider.middlewares.MyspiderDownloaderMiddleware': 543,
#}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
#}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# 开启管道类才能写入数据
ITEM_PIPELINES = {
   'mySpider.pipelines.MyspiderPipeline': 300,
}

# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False

# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'

注意:

  • scrapy.Spider爬虫类中必须有名为parse的解析
  • 如果网站结构层次比较复杂,也可以自定义其他解析函数
  • 在解析函数中提取的url地址如果要发送请求,则必须属于allowed_domains范围内,但是start_urls中的url地址不受这个限制,我们会在后续的课程中学习如何在解析函数中构造发送请求
  • 启动爬虫的时候注意启动的位置,是在项目路径下启动
  • parse()函数中使用yield返回数据,注意:解析函数中的yield能够传递的对象只能是:BaseItem, Request, dict, None

**5.**保存数据

利用管道pipeline来处理(保存)数据

5.1 在pipelines.py文件中定义对数据的操作

  1. 定义一个管道类

  2. 重写管道类的process_item方法

  3. process_item方法处理完item之后必须返回给引擎

    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

    import json

    from itemadapter import ItemAdapter

    class MyspiderPipeline:
    def init(self):
    self.file = open('lianjia.json','w')

     # 爬虫文件中提取数据的方法每yield一次item,就会运行一次
     # 该方法为固定名称函数
     def process_item(self, item, spider):
         # 参数item默认是一个 <class 'mySpider.items.MyspiderItem'>类信息,需要处理成字典
         dict_data = dict(item)
         print(type(item), type(dict_data))
         # 将返回的字典数据转为JSON数据
         json_data = json.dumps(dict_data,ensure_ascii=False)+',\n'
         # 写入JSON数据
         self.file.write(json_data)
         # 参数item:是爬虫文件中yield的返回的数据对象(引擎会把这个交给管道中的这个item参数)
         print("建模之后的返回值:",item,)
         # 默认使用完管道之后将数据又返回给引擎
         return item
    
     def __del__(self):
         self.file.close()
    

5.2 在settings.py配置启用管道

#   设置目录文件               该值的大小决定管道执行的顺序,值越小优先级越高(该值最好 不要大于1000)  
ITEM_PIPELINES = {
   'mySpider.pipelines.MyspiderPipeline': 300,
}

以上配置项中键为使用的管道类,管道类使用.进行分割,第一个为项目目录,第二个为文件,第三个为定义的管道类。

配置项中值为管道的使用顺序,设置的数值约小越优先执行,该值一般设置为1000以内。

6.运行scrapy

第一种:

命令:在项目目录下执行scrapy crawl <爬虫名字>

示例:scrapy crawl 爬虫名字 --nolog 忽略日志信息

第二种:

写一个再爬虫项目根目录中创建.py结尾的文件,执行以下指令:

from scrapy import cmdline

cmdline.execute(['scrapy','crawl','lianjia'])

7.翻页请求的思路

对于要提取如下图中所有页面上的数据该怎么办?

回顾requests模块是如何实现翻页请求的:

  1. 找到下一页的URL地址
  2. 调用requests.get(url)

scrapy实现翻页的思路:(scrapy并无单独的url这个概念,scrapy中都是需要将url打包成一个请求对象)

  1. 找到下一页的url地址
  2. 把url地址构造成请求对象,传递给引擎

8.如何构造Request对象,并发送请求

实现方法

  1. 确定url地址
  2. 构造请求,scrapy.Request(url,callback)
    • callback:指定响应体解析的函数名称,表示该请求返回的响应使用哪一个函数进行解析(callback不赋值的话默认是给parse方法解析)
  3. 把请求交给引擎:yield scrapy.Request(url,callback)

链家爬虫

通过爬取链家页面信息,学习如何实现翻页请求
地址:襄阳租房信息_襄阳出租房源|房屋出租价格【襄阳贝壳租房】

思路分析:

  1. 获取首页的响应数据(因为里面有我们想要的翻页链接)
  2. 寻找下一页的地址,进行翻页,获取数据

三、scrapy总结

  1. scrapy的安装:pip install scrapy
  2. 创建scrapy的项目: scrapy startproject myspider
  3. 创建scrapy爬虫:在项目目录下执行 scrapy genspider lianjia lianjia.com
  4. 运行scrapy爬虫:在项目目录下执行scrapy crawl 爬虫名字 【scrapy crawl 爬虫名字 --nolog 忽略日志信息】
  5. 解析并获取scrapy爬虫中的数据:
    1. response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法
    2. extract() 返回一个包含有字符串的列表
    3. extract_first() 返回列表中的第一个字符串,列表为空没有返回None
  6. scrapy管道的基本使用:
    1. 完善pipelines.py中的process_item方法
    2. 在settings.py中设置开启pipeline
  7. response响应对象的常用属性
    1. response.url:获取当前响应的url地址
    2. response.request.url:获取当前响应对应的请求的url地址
    3. response.headers:获取响应头
    4. response.urljoin(url) :用于构造绝对url, 当传入的url参数是一个相对地址时, 根据response.url计算出相应的绝对url.
    5. response.body:获取响应体,也就是html代码,byte类型
    6. response.text: 获取响应体,str类型
    7. response.status:获取响应状态码
  8. request请求对象的常用属性
    1. request.url(必选):请求页面的url地址,bytes或str类型。
    2. request.callback:页面解析函数,Callback类型,Request请求对象的页面下载完成后,由该参数指定的页面解析函数解析页面,如果未传递该参数,默认调用Spider的parse方法。
    3. request.method:HTTP请求的方法,默认为'GET'。
    4. request.headers:HTTP请求的头部字典,dict 类型。
    5. request.meta:Request 的元数据字典,dict 类型,用于给框架中其他组件传递信息,比如中间件 Item Pipeline。其他组件可以使用Request 对象的 meta 属性访问该元数据字典 (request.meta), 也用于给响应处理函数传递信息。
    6. request.encoding:url 和 body 参数的编码默认为'utf-8'。如果传入的url或body参数是str 类型,就使用该参数进行编码。
    7. request.dont_filter:默认情况下(dont_filter=False),对同一个url地址多次提交下载请求,后面的请求会被去重过滤器过滤(避免重复下载)。如果将该参数置为True,可以使请求避免被过滤,强制下载。例如:在多次爬取一个内容随时间而变化的页面时(每次使用相同的url),可以将该参数设置为True。
相关推荐
兆。1 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
API快乐传递者7 小时前
淘宝反爬虫机制的主要手段有哪些?
爬虫·python
兜里有糖请分享18 小时前
Python中序列化/反序列化JSON格式的数据
爬虫·python
亿牛云爬虫专家1 天前
用Puppeteer点击与数据爬取:实现动态网页交互
javascript·爬虫·爬虫代理·puppeteer·数据·代理ip·16yun
API快乐传递者1 天前
利用Python 的爬虫技术淘宝天猫销量和库存
开发语言·爬虫·python
操练起来1 天前
【Python实战案例】爬虫项目实例(附赠源码)
数据库·爬虫·python
编码小袁1 天前
利用爬虫爬取网站信息
爬虫
孤寒者1 天前
【实战篇】requests库 - 有道云翻译爬虫 【附:代理IP的使用】
爬虫·代理ip·隧道代理·有道云翻译爬虫·青果代理ip
=(^.^)=哈哈哈1 天前
从安全角度看多线程(附Golang举例)
爬虫·python·golang
Python_trys2 天前
Python网络爬虫入门篇!
开发语言·爬虫·python