爬虫之scrapy框架

1.scrapy框架介绍

  Scrapy是用纯Python实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架

  Scrapy 特色是使用了 Twisted异步网络框架来处理网络通讯,加快了下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求

1.1 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中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)

注意!只有当调度器中不存在任何request了,整个程序才会停止,(也就是说,对于下载失败的URL,Scrapy也会重新下载。)

官方文档0.25链接

最新官方文档1.5链接

以上参考链接

1.2 scrapy安装

#Windows平台
    1、pip3 install wheel
    #安装后,便支持通过wheel文件安装软件
    3、pip3 install lxml
    4、pip3 install pyopenssl
    5、下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/
    # 根据电脑Python版本和位数下载并安装最新版的pywin32,它会自动寻找Python的安装路径,所以不需要做任何修改,一直单击【下一步】即可。
    # 这里有时候会报停止工作,但是通过pip3 list 命令可以看到他已经存在
    6、下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
    7、执行pip3 install 下载目录路径\Twisted-17.9.0-cp36-cp36m-win_amd64.whl
    # Scrapy需要依赖Twisted。Twisted是Python下面一个非常重要的基于事件驱动的IO引擎。Twisted的安装依赖于pywin32
    8、pip3 install scrapy

#Linux平台
    1、pip3 install scrapy

# 这里安装好pywin32后,后期可能还是无法运行(报ImportError: DLL load failed错误),这里一般都是我们该模块安装的有问题导致的,这里可以参考知乎或者参考Stack Overflow

我的是参考Stack Overflow下的说明,执行了 pip install win10toast --ignore-installed 才好的

1.3 命令行相关指令

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

# 2 有两种命令:其中Project-only必须切到项目文件夹下才能执行,而Global的命令则不需要
    Global commands:
        startproject #创建项目
        genspider    #创建爬虫程序
        settings     #如果是在项目目录下,则得到的是该项目的配置
        runspider    #运行一个独立的python文件,不必创建项目
        shell        #scrapy shell url地址  在交互式调试,如选择器规则正确与否
        fetch        #独立于程单纯地爬取一个页面,可以拿到请求头
        view         #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求
        version      #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本
    Project-only commands:
        crawl        #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = False
        check        #检测项目中有无语法错误
        list         #列出项目中所包含的爬虫名
        edit         #编辑器,一般不用
        parse        #scrapy parse url地址 --callback 回调函数  #以此可以验证我们的回调函数是否正确
        bench        #scrapy bentch压力测试

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

1.4 框架结构

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

‘‘‘

1.5 项目流程

新建项目 (scrapy startproject xxx):新建一个新的爬虫项目
明确目标 (编写items.py):明确你想要抓取的目标
制作爬虫 (spiders/xxspider.py):制作爬虫开始爬取网页
存储内容 (pipelines.py):设计管道存储爬取内容

1.6 启动一个项目

1 scrapy startproject DianShang   # 创建爬虫项目
2 scrapy genspider jd jd.com      # 生成一个爬虫程序
3 scrapy crawl jd                 # 运行scrapy项目

现在我们有了基本的项目骨架

1.7 spider类的说明

  Spiders是为站点爬网和解析页面定义自定义行为的地方

spiders下的jd.py文件

# -*- coding: utf-8 -*-
import scrapy

class JdSpider(scrapy.Spider):
    name = ‘jd‘
    allowed_domains = [‘jd.com‘]
    start_urls = [‘http://jd.com/‘]

    def parse(self, response):
        pass

Spider类中的start_requests方法:

    def start_requests(self):
        cls = self.__class__
        if method_is_overridden(cls, Spider, ‘make_requests_from_url‘):
            warnings.warn(
                "Spider.make_requests_from_url method is deprecated; it "
                "won‘t be called in future Scrapy releases. Please "
                "override Spider.start_requests method instead (see %s.%s)." % (
                    cls.__module__, cls.__name__
                ),
            )
            for url in self.start_urls:
                yield self.make_requests_from_url(url)
        else:
            for url in self.start_urls:
                yield Request(url, dont_filter=True)

  有时候后台的start_requests方法会访问不到我们的目标站点,我们大多数情况需要自己构造此方法,它的最终返回值是用生成器yield返回的,我们自己写也建议使用生成器。

start_requests方法它默认的回调函数就是parse

2. 创建项目

  我们的目标是爬取亚马逊商城iphoex的名称,价格以及配送方,注意的是:我们需要的这些信息都在手机详情页面,而在手机列表页面只有我们点击它的图片或者文字才会看到手机详细信息

  想要获取手机的信息,现在我们需要进行分布爬取,第一次先获取每一个手机详情页面的url,可以通过手机列表页面的图片进行获取,也能通过文字获取,然后通过二次解析去拿到我们需要的信息

  拿到信息后,通过MongoDB对我们的信息做持久化处理

2.1 创建项目文件

爬虫Scrapy命令:
    1 scrapy startproject Amazon         # 创建爬虫项目
    2 scrapy genspider amazon amazon.cn      # 生成一个爬虫程序
    3 scrapy crawl amazon                   # 运行scrapy项目

创建好后 spiders下自动生成的amazon.py文件

# -*- coding: utf-8 -*-
import scrapy

class AmazonSpider(scrapy.Spider):
    name = ‘amazon‘
    allowed_domains = [‘amazon.cn‘]
    start_urls = [‘http://amazon.cn/‘]

    def parse(self, response):
        pass

2.2 创建启动文件

  创建好后,它默认只能在终端运行,我们可以在它的根目录下创建一个bin.py文件,来作为它的执行文件

from scrapy.cmdline import execute

execute(["scrapy","crawl","amazon",‘--nolog‘])  # 不打印日志信息

  如果不需要相关日志信息,,可以在列表后面追加一个参数:‘--nolog‘

2.3 关闭ROBOTSTXT_OBEY命令

  关闭setting下的ROBOTSTXT_OBEY命令,该命令的作用是让你遵循爬虫协议的情况下爬取相关内容,我们为了避免它对我们爬取时的影响,可以把他修改为False

2.4 获取商品信息

 获取商品列表的详情链接

amazon.py

import scrapy
from scrapy import Request  # 导入模块

class AmazonSpider(scrapy.Spider):
    name = ‘amazon‘
    allowed_domains = [‘amazon.cn‘]
    # 自定义配置,在Spider中custom_settings设置的是None
    custom_settings = {
        ‘REQUEST_HEADERS‘: {
            ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36‘,
        }
    }

    def start_requests(self):
        r1 = Request(
                    url="https://www.amazon.cn/s/ref=nb_sb_ss_i_3_6?field-keywords=iphonex",
                     headers=self.settings.get(‘REQUEST_HEADERS‘),
                     )
        yield r1

    def parse(self, response):
        # 获取商品名
        # detail_urls = response.xpath(‘//*[@id="result_0"]/div/div[3]/div[1]/a/h2‘).extract()
        # 商品单个商品详情链接
        # detail_urls = response.xpath(‘//*[@id="result_0"]/div/div[3]/div[1]/a/@href‘).extract()
        # 获取整个页面商品详情链接
        # detail_urls = response.xpath(‘//li[contains(@id,"result_")]/div/div[3]/div[1]/a/@href‘).extract()
        detail_urls = response.xpath(‘//*[starts-with(@id,"result")]/div/div[3]/div[1]/a/@href‘).extract()

        print(detail_urls)

现在让scrapy去访问这些链接,只要parse函数返回一个Request对象,它就会放到异步请求列表里面,并由twisted发送异步请求

import scrapy
from scrapy import Request  # 导入模块

class AmazonSpider(scrapy.Spider):
    name = ‘amazon‘
    allowed_domains = [‘amazon.cn‘]
    # 自定义配置,在Spider中custom_settings设置的是None
    custom_settings = {
        ‘REQUEST_HEADERS‘: {
            ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36‘,
        }
    }

    def start_requests(self):
        r1 = Request(
            url="https://www.amazon.cn/s/ref=nb_sb_ss_i_3_6?field-keywords=iphonex",
            headers=self.settings.get(‘REQUEST_HEADERS‘),
        )
        yield r1

    def parse(self, response):
        # 获取商品名
        # detail_urls = response.xpath(‘//*[@id="result_0"]/div/div[3]/div[1]/a/h2‘).extract()
        # 商品单个商品详情链接
        # detail_urls = response.xpath(‘//*[@id="result_0"]/div/div[3]/div[1]/a/@href‘).extract()
        # 获取整个页面商品详情链接
        # detail_urls = response.xpath(‘//li[contains(@id,"result_")]/div/div[3]/div[1]/a/@href‘).extract()
        detail_urls = response.xpath(‘//*[starts-with(@id,"result")]/div/div[3]/div[1]/a/@href‘).extract()

        for url in detail_urls:
            yield Request(url=url,
                          headers=self.settings.get(‘REQUEST_HEADERS‘),  # 请求头
                          callback=self.parse_detail,  # 回调函数
                          dont_filter=True  # 不去重
                          )

    def parse_detail(self, response):  # 获取商品详细信息
        # 商品名,获取第一个结果
        name = response.xpath(‘//*[@id="productTitle"]/text()‘).extract_first()
        if name:
            name = name.strip()
        # 商品价格
        price = response.xpath(‘//*[@id="priceblock_ourprice"]/text()‘).extract_first()
        # 配送方式
        delivery = response.xpath(‘//*[@id="ddmMerchantMessage"]/*[1]/text()‘).extract_first()

        print(name, price, delivery)

2.5 存储商品信息到MongoDB

  我们需要使用items.py文件

import scrapy

# 获取你想要的字段
class AmazonItem(scrapy.Item):
    # define the fields for your item here
    name = scrapy.Field()
    price= scrapy.Field()
    delivery=scrapy.Field()

  并修改amazon.py最后的数据返回值

amazon.py

import scrapy
from scrapy import Request  # 导入模块
from Amazon.items import AmazonItem

class AmazonSpider(scrapy.Spider):
    name = ‘amazon‘
    allowed_domains = [‘amazon.cn‘]
    # 自定义配置,在Spider中custom_settings设置的是None
    custom_settings = {
        ‘REQUEST_HEADERS‘: {
            ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36‘,
        }
    }

    def start_requests(self):
        r1 = Request(
            url="https://www.amazon.cn/s/ref=nb_sb_ss_i_3_6?field-keywords=iphonex",
            headers=self.settings.get(‘REQUEST_HEADERS‘),
        )
        yield r1

    def parse(self, response):
        # 获取商品名
        # detail_urls = response.xpath(‘//*[@id="result_0"]/div/div[3]/div[1]/a/h2‘).extract()
        # 商品单个商品详情链接
        # detail_urls = response.xpath(‘//*[@id="result_0"]/div/div[3]/div[1]/a/@href‘).extract()
        # 获取整个页面商品详情链接
        # detail_urls = response.xpath(‘//li[contains(@id,"result_")]/div/div[3]/div[1]/a/@href‘).extract()
        detail_urls = response.xpath(‘//*[starts-with(@id,"result")]/div/div[3]/div[1]/a/@href‘).extract()

        for url in detail_urls:
            yield Request(url=url,
                          headers=self.settings.get(‘REQUEST_HEADERS‘),  # 请求头
                          callback=self.parse_detail,  # 回调函数
                          dont_filter=True  # 不去重
                          )

    def parse_detail(self, response):  # 获取商品详细信息
        # 商品名,获取第一个结果
        name = response.xpath(‘//*[@id="productTitle"]/text()‘).extract_first()
        if name:
            name = name.strip()
        # 商品价格
        price = response.xpath(‘//*[@id="priceblock_ourprice"]/text()‘).extract_first()
        # 配送方式
        delivery = response.xpath(‘//*[@id="ddmMerchantMessage"]/*[1]/text()‘).extract_first()

        # 生成标准化数据

        item = AmazonItem()  # 实例化
        # 增加键值对
        item["name"] = name
        item["price"] = price
        item["delivery"] = delivery

        return item     # 返回的是一个字典

  处理Spider中获取到的Item ,需要PipeLine将数据储存到MongoDB中

pipelines.py

from pymongo import MongoClient

class MongodbPipeline(object):

    def __init__(self, host, port, db, table):
        self.host = host
        self.port = port
        self.db = db
        self.table = table

    @classmethod
    def from_crawler(cls, crawler):
        """
        Scrapy会先通过getattr判断我们是否自定义了from_crawler,有则调它来完
        成实例化
        """
        HOST = crawler.settings.get(‘HOST‘)
        PORT = crawler.settings.get(‘PORT‘)
        DB = crawler.settings.get(‘DB‘)
        TABLE = crawler.settings.get(‘TABLE‘)
        return cls(HOST, PORT, DB, TABLE)

    def open_spider(self, spider):
        """
        爬虫刚启动时执行一次
        """
        # self.client = MongoClient(‘mongodb://%s:%[email protected]%s:%s‘ %(self.user,self.pwd,self.host,self.port))
        self.client = MongoClient(host=self.host, port=self.port)

    def close_spider(self, spider):
        """
        爬虫关闭时执行一次
        """
        self.client.close()

    def process_item(self, item, spider):
        # 操作并进行持久化
        d = dict(item)
        if all(d.values()):
            self.client[self.db][self.table].insert(d)
            print("添加成功一条")

  修改settings.py,在下面增加MongoDB连接信息

# MongoDB连接信息
HOST="127.0.0.1"
PORT=27017
DB="amazon"  # 数据库名
TABLE="goods"  # 表名

  同时开启MongoDB的PipeLine信息,注意这里开启后还需要进行修改,我们pipelines下的名称是MongodbPipeline

ITEM_PIPELINES = {
   ‘Amazon.pipelines.MongodbPipeline‘: 300,
}

此时在cmd下启动我们的mongodb(mongod),进入我们的数据库(mongo),并自行创建数据库

执行我们的bin文件,此时会在你会发现数据都存储进我们的数据库内

原文地址:https://www.cnblogs.com/LearningOnline/p/9733519.html

时间: 2024-10-02 22:25:58

爬虫之scrapy框架的相关文章

Python网络爬虫之Scrapy框架(CrawlSpider)

目录 Python网络爬虫之Scrapy框架(CrawlSpider) CrawlSpider使用 爬取糗事百科糗图板块的所有页码数据 Python网络爬虫之Scrapy框架(CrawlSpider) 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效). CrawlSpider使

网络爬虫之scrapy框架详解,scrapy框架设置代理

twisted介绍 Twisted是用Python实现的基于事件驱动的网络引擎框架,scrapy正是依赖于twisted, 它是基于事件循环的异步非阻塞网络框架,可以实现爬虫的并发. twisted是什么以及和requests的区别: request是一个python实现的可以伪造浏览器发送Http请求的模块,它封装了socket发送请求 twisted是基于时间循环的异步非阻塞的网络框架,它也封装了socket发送请求,但是他可以单线程的完成并发请求. twisted的特点是: 非阻塞:不等待

爬虫学习 16.Python网络爬虫之Scrapy框架(CrawlSpider)

爬虫学习 16.Python网络爬虫之Scrapy框架(CrawlSpider) 引入 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效). 今日概要 CrawlSpider简介 CrawlSpider使用 基于CrawlSpider爬虫文件的创建 链接提取器 规则解析器 今日详

python爬虫之scrapy框架

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrapy 使用了 Twisted异步网络库来处理网络通讯.整体架构大致如下 Scrapy主要包括了以下组件: 引擎

Python爬虫进阶(Scrapy框架爬虫)

准备工作:           配置环境问题什么的我昨天已经写了,那么今天直接安装三个库                        首先第一步:                            (我们要用到scrapy框架,在python里调用windows 命令,使用mongodb存储爬到的数据 )                                  进入DOS python/Script>路径下  输入命令: python/Script> pip install p

Requests爬虫和scrapy框架多线程爬虫

1.基于Requests和BeautifulSoup的单线程爬虫 1.1 BeautifulSoup用法总结 1. find,获取匹配的第一个标签 tag = soup.find('a') print(tag) tag = soup.find(name='a', attrs={'class': 'sister'}, recursive=True, text='Lacie') tag = soup.find(name='a', class_='sister', recursive=True, te

python爬虫随笔-scrapy框架(1)——scrapy框架的安装和结构介绍

scrapy框架简介 Scrapy,Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试.(引用自:百度百科) scrapy官方网站:https://scrapy.org/ scrapy官方文档:https://doc.scrapy.org/en/latest/ scrapy框架安装 首先我们安装scrapy,使用如下命令 pip install scrapy 此时很多人应该都会遇到如

18、python网路爬虫之Scrapy框架中的CrawlSpider详解

CrawlSpider的引入: 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效) CrawlSpider的简介: CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能.其中最显著的功能就是"

5 爬虫之scrapy框架

一 scrapy框架简介 1 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前Scrapy的用途十分广泛,可用于如数据挖掘.监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫.Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架.