scrapy 订阅
Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。 [1]  Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。 [2] 展开全文
Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。 [1]  Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。 [2]
信息
外文名
scrapy
基本功能
数据挖掘
特    点
应用框架
中文名
抓取
应    用
数据挖掘、监测和自动化测试
scrapy基本功能
Scrapy是一个适用爬取网站数据、提取结构性数据的应用程序框架,它可以应用在广泛领域:Scrapy 常应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。通常我们可以很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片。 [3]  尽管Scrapy原本是设计用来屏幕抓取(更精确的说,是网络抓取),但它也可以用来访问API来提取数据。
收起全文
精华内容
下载资源
问答
  • scrapy

    千次阅读 2020-06-29 20:05:37
    scrapy 安装 scrapy 脚本 scrapy startproject mySpider scrapy genspider scrapy list scrapy genspider itcast “itcast.cn” scrapy crawl itcast

    scrapy 安装

    scrapy 脚本

    scrapy startproject mySpider
    scrapy genspider
    scrapy list
    scrapy genspider itcast “itcast.cn”
    scrapy crawl itcast

    展开全文
  • Scrapy

    千次阅读 多人点赞 2018-08-01 23:10:29
    Scrapy介绍  Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓取)所设计的,使用它可以快速、简单、可扩展 的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如挖掘、...

    Scrapy介绍

         Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓取)所设计的,使用它可以快速、简单、可扩展

    的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如挖掘、监测和自动化测试等领域,也可以应用在API

    所返回的数据(例如Amazon Associates Web Services)或者通用的网络爬虫。

          Scrapy是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。整体架构大致如下

    Scrapy数据流是由执行的核心引擎(engine)控制,流程是这样的:

    1.引擎打开一个网站(open adomain),找到处理该网站的Spider并向该spider请求第一个要抓取的URL(s)。

    2.引擎从Spider中获取到第一个要抓取的URL并在调度器(Scheduler)以Request调度。

    3.引擎向调度器请求下一个要爬取的URL。

    4.调度器返回下一个要抓取的URL给引擎,引擎将URL通过下载中间件(请求(request)方向)转发给下载器(Downloader).

    5.一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方向)发送给引擎。

    6.引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。

    7.Spider处理Response并返回爬取到的Item给Item Pipeline,将(Spider返回的)Request给调度器。

    8.引擎将(Spider返回的)爬取的Item给Item Pipeline,将(Spider返回的)Request给调度器。

    9.(从第二步)重复直到调度器中没有更多地request,引擎关闭该网站。

    Scrapy主要包括了一下组件:

    1.爬虫引擎(engine):爬虫引擎负责控制各个组件之间的数据流,当某些操作触发事件后都是通过engine来处理

    2.调度器:调度接收来engine的请求并将请求请求放入队列中,并通过事件返回给engine

    3.下载器:通过engine请求下载网络数据并将结果响应给engine

    4.spider:Spider发出请求,并处理engine返回给它下载器响应数据,以items和规则内的数据请求(urls)返回给engine

    5.管道数目(item pipeline):负责处理engine返回spider解析后的数据,并且将数据持久化,例如将数据存入数据库或者文件

    6.下载中间件:下载中间件是engine和下载器交互组件,以钩子(插件)的形式存在,可以代替接收请求、处理数据的下载以及

                              将结果响应给engine

    7.spider中间件:spider中间件是engine和spider之间的交互组件,以钩子(插件)的形式存在,可以代替处理response以及返回

                                给engine items及新的请求集


    windows环境配置

    Scrapy依赖包(也可到官网单独下载各文件安装):

    1.lxml: pip install wheel

    2.zope.interface:pip install zope.interface-4.3.3-cp35-cp35m-win_amd64.whl

    3.pyOpenSSL:pip install pyOpenSSL

    4.Twisted:pip install Twisted

    5.Scrapy:pip install Scrapy

    Anoconda+Pycharm+Scrapy Anaconda是包含了常用的数据科学库的Python发行版本,如果没有安装,

    可以到http://www.continuum.io/downloads下载对应平台的包安装。如果已经安装,那么可以轻松地通过

    conda命令安装Scrapy。conda install scrapy


    Scrapy安装完成后,打开命令行终端输入scrapy,显示如下:

    创建项目

    • 创建爬虫项目命令
    scrapy startproject project_name
    
    • 创建爬虫文件命令
    scrapy genspider example exameple.com
    • 文件目录如下
      D:\test>tree /F
    卷 软件 的文件夹 PATH 列表
    卷序列号为 58B6-0E53
    D:.
    └─project_dir
      │  scrapy.cfg
      │
      └─project_name
          │  items.py
          │  middlewares.py
          │  pipelines.py
          │  settings.py
          │  __init__.py
          │
          ├─spiders
          │  │  __init__.py
          │  │
          │  └─__pycache__
          └─__pycache__

    items.py:定义爬虫程序的数据模型,类似于实体类。

    middlewares.py:爬虫中间件,负责调度。

    pipelines.py:管道文件,负责对spider返回数据的处理。

    spiders目录 负责存放继承自scrapy的爬虫类

    scrapy.cfg.scrapy 基础配置

    init:初始化文件

    setting.py:负责对整个爬虫的配置,内容如下

      # -*- coding: utf-8 -*-
    
      # Scrapy settings for baidu project
      #
      # For simplicity, this file contains only settings considered important or
      # commonly used. You can find more settings consulting the documentation:
      #
      #     https://doc.scrapy.org/en/latest/topics/settings.html
      #     https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
      #     https://doc.scrapy.org/en/latest/topics/spider-middleware.html
    
      BOT_NAME = 'baidu'
    
      # 爬虫所在地
      SPIDER_MODULES = ['baidu.spiders']
      NEWSPIDER_MODULE = 'baidu.spiders'
    
    		
      # Crawl responsibly by identifying yourself (and your website) on the user-agent
      #USER_AGENT = 'baidu (+http://www.yourdomain.com)'
    
      # Obey robots.txt rules
      # 遵守爬虫协议
      ROBOTSTXT_OBEY = False
    
      # Configure maximum concurrent requests performed by Scrapy (default: 16)
      # 最大请求并发量 默认16
      # CONCURRENT_REQUESTS = 32
    
      # configure 配置 请求延迟
      # Configure a delay for requests for the same website (default: 0)
      # See https://doc.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)
      # 是否使用cookie
      #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://doc.scrapy.org/en/latest/topics/spider-middleware.html
      #SPIDER_MIDDLEWARES = {
      #         值越小,优先级越高,优先级越高,越先执行
      #    'baidu.middlewares.BaiduSpiderMiddleware': 543,
      #}
    
      # Enable or disable downloader middlewares
      # See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
      #DOWNLOADER_MIDDLEWARES = {
      #         值越小,优先级越高,优先级越高,越先执行
      #    'baidu.middlewares.BaiduDownloaderMiddleware': 543,
      #}
    
      # Enable or disable extensions 是否进行扩展
      # See https://doc.scrapy.org/en/latest/topics/extensions.html
      #EXTENSIONS = {
      #    'scrapy.extensions.telnet.TelnetConsole': None,
      #}
    
      # Configure item pipelines
      # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
      ITEM_PIPELINES = {
          # 值越小,优先级越高,优先级越高,越先执行
         'baidu.pipelines.BaiduPipeline': 1,
      }
    
      # Enable and configure the AutoThrottle extension (disabled by default)
      # See https://doc.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://doc.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结合selenium解析动态页面

    万次阅读 多人点赞 2020-07-20 21:52:24
    scrapy解决动态页面的一个解决办法,scrapy结合selenium解析动态页面

    scrapy结合selenium解析动态页面

    1. 问题

    虽然scrapy能够完美且快速的抓取静态页面,但是在现实中,目前绝大多数网站的页面都是动态页面,动态页面中的部分内容是浏览器运行页面中的JavaScript脚本动态生成的,爬取相对困难;

    比如你信心满满的写好了一个爬虫,写好了目标内容的选择器,一跑起来发现根本找不到这个元素,当时肯定一万个黑人问号

    于是你在浏览器里打开F12,一顿操作,发现原来这你妹的是ajax加载的,不然就是硬编码在js代码里的,blabla的…

    然后你得去调ajax的接口,然后解析json啊,转成python字典啊,然后才能拿到你想要的东西

    妹的就不能对我们这些小爬爬友好一点吗?

    于是大家伙肯定想过,“为啥不能浏览器看到是咋样的html页面,我们爬虫得到的也是同样的html页面呢? 要是可以,那得多么美滋滋啊”

    2. 解决方案

    既然是想要得到和浏览器一模一样的html页面,那我们就先用浏览器渲染一波目标网页,然后再将浏览器渲染后的html拿给scrapy进行进一步解析不就好了吗

    2.1 获取浏览器渲染后的html

    有了思路,肯定是网上搜一波然后开干啊,搜python操作浏览器的库啊

    货比三家之后,找到了selenium这货

    selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题。

    卧槽,这就是我们要的东西啦

    先试一波看看效果如何,目标网址http://quotes.toscrape.com/js/

    别着急,先来看一下网页源码


    我们想要的div.quote被硬编码在js代码中

    用selenium试一下看能不能获取到浏览器渲染后的html

    from selenium import webdriver
    
    # 控制火狐浏览器
    browser = webdriver.Firefox()
    
    # 访问我们的目标网址
    browser.get("http://quotes.toscrape.com/js/")
    
    # 获取渲染后的html页面
    html = browser.page_source
    

    perfect,到这里我们已经顺利拿到浏览器渲染后的html了,selenium大法好啊?

    2.2 通过下载器中间件返回渲染过后html的Response

    这里先放一张scrapy的流程图

    在这里插入图片描述

    所以我们只需要在scrapy下载网页(downloader下载好网页,构造Response返回)之前,通过下载器中间件返回我们自己<通过渲染后html构造的Response>不就可以了吗?

    道理我都懂,关键是在哪一步使用浏览器呢?

    分析:
    (1)我们的scrapy可能是有很多个爬虫的,有些爬虫处理的是纯纯的静态页面,而有些是处理的纯纯的动态页面,又有些是动静态结合的页面(有可能列表页是静态的,正文页是动态的),如果把<浏览器调用代码>放在下载器中间件中,那么除非特别区分哪些爬虫需要selenium,否则每一个爬虫都用selenium去下载解析页面的话,实在是太浪费资源了,就相当于杀鸡用牛刀了,所以得出结论,<浏览器调用代码>应该是放置于Spider类中更好一点;

    (2)如果放置于Spider类中,就意味着一个爬虫占用一个浏览器的一个tab页,如果这个爬虫里的某些Request需要selenium,而某些不需要呢? 所以我们还要在区分一下Request;

    结论:

    1. SeleniumDownloaderMiddleware(selenium专用下载器中间件):负责返回浏览器渲染后的Response
    2. SeleniumSpider(selenium专用Spider):一个spider开一个浏览器
    3. SeleniumRequest:只是继承一下scrapy.Request,然后pass,好区分哪些Request需要启用selenium进行解析页面,相当于改个名

    3. 撸代码,盘他

    3.1 自定义Request

    #!usr/bin/env python  
    # -*- coding:utf-8 _*-
    """ 
    @author:Joshua
    @description:
        只是继承一下scrapy.Request,然后pass,好区分哪些Request需要启用selenium进行解析页面,相当于改个名
    """
    import scrapy
    
    class SeleniumRequest(scrapy.Request):
        """
        selenium专用Request类
        """
        pass
    

    3.2 自定义Spider

    #!usr/bin/env python  
    # -*- coding:utf-8 _*-
    """ 
    @author:Joshua 
    @description:
        一个spider开一个浏览器
    """
    import logging
    import scrapy
    from selenium import webdriver
    
    
    class SeleniumSpider(scrapy.Spider):
        """
        Selenium专用spider
    
        一个spider开一个浏览器
    
        浏览器驱动下载地址:http://www.cnblogs.com/qiezizi/p/8632058.html
        """
        # 浏览器是否设置无头模式,仅测试时可以为False
        SetHeadless = True
    
        # 是否允许浏览器使用cookies
        EnableBrowserCookies = True
    
        def __init__(self, *args, **kwargs):
            super(SeleniumSpider, self).__init__(*args, **kwargs)
            
            # 获取浏览器操控权
            self.browser = self._get_browser()
    
        def _get_browser(self):
            """
            返回浏览器实例
            """
            # 设置selenium与urllib3的logger的日志等级为ERROR
            # 如果不加这一步,运行爬虫过程中将会产生一大堆无用输出
            logging.getLogger('selenium').setLevel('ERROR')
            logging.getLogger('urllib3').setLevel('ERROR')
            
            # selenium已经放弃了PhantomJS,开始支持firefox与chrome的无头模式
            return self._use_firefox()
    
        def _use_firefox(self):
            """
            使用selenium操作火狐浏览器
            """
            profile = webdriver.FirefoxProfile()
            options = webdriver.FirefoxOptions()
            
            # 下面一系列禁用操作是为了减少selenium的资源耗用,加速scrapy
            
            # 禁用图片
            profile.set_preference('permissions.default.image', 2)
            profile.set_preference('browser.migration.version', 9001)
            # 禁用css
            profile.set_preference('permissions.default.stylesheet', 2)
            # 禁用flash
            profile.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', 'false')
            
            # 如果EnableBrowserCookies的值设为False,那么禁用cookies
            if hasattr(self, "EnableBrowserCookies") and self.EnableBrowserCookies:
                # •值1 - 阻止所有第三方cookie。
                # •值2 - 阻止所有cookie。
                # •值3 - 阻止来自未访问网站的cookie。
                # •值4 - 新的Cookie Jar策略(阻止对跟踪器的存储访问)
                profile.set_preference("network.cookie.cookieBehavior", 2)
            
            # 默认是无头模式,意思是浏览器将会在后台运行,也是为了加速scrapy
            # 我们可不想跑着爬虫时,旁边还显示着浏览器访问的页面
            # 调试的时候可以把SetHeadless设为False,看一下跑着爬虫时候,浏览器在干什么
            if self.SetHeadless:
                # 无头模式,无UI
                options.add_argument('-headless')
    
            # 禁用gpu加速
            options.add_argument('--disable-gpu')
    
            return webdriver.Firefox(firefox_profile=profile, options=options)
    
        def selenium_func(self, request):
            """
            在返回浏览器渲染的html前做一些事情
                1.比如等待浏览器页面中的某个元素出现后,再返回渲染后的html;
                2.比如将页面切换进iframe中的页面;
            
            在需要使用的子类中要重写该方法,并利用self.browser操作浏览器
            """
            pass
    
        def closed(self, reason):
            # 在爬虫关闭后,关闭浏览器的所有tab页,并关闭浏览器
            self.browser.quit()
            
            # 日志记录一下
            self.logger.info("selenium已关闭浏览器...")
    
    

    之所以不把获取浏览器的具体代码写在__init__方法里,是因为笔者之前写的代码里考虑过

    1. 两种浏览器的调用(支持firefox与chrome),虽然后来感觉还是firefox比较方便,因为所有版本的火狐浏览器的驱动都是一样的,但是谷歌浏览器是不同版本的浏览器必须用不同版本的驱动(坑爹啊- -’’)
    2. 自动区分不同的操作系统并选择对应操作系统的浏览器驱动

    额… 所以上面spider的代码是精简过的版本

    备注: 针对selenium做了一系列的优化加速,启用了无头模式,禁用了css、flash、图片、gpu加速等… 因为爬虫嘛,肯定是跑的越快越好啦?

    3.3 自定义下载器中间件

    #!usr/bin/env python  
    # -*- coding:utf-8 _*-
    """ 
    @author:Joshua 
    @description:
        负责返回浏览器渲染后的Response
    """
    import hashlib
    import time
    from scrapy.http import HtmlResponse
    from twisted.internet import defer, threads
    from tender_scrapy.extendsion.selenium.spider import SeleniumSpider
    from tender_scrapy.extendsion.selenium.requests import SeleniumRequest
    
    
    class SeleniumDownloaderMiddleware(object):
        """
        Selenium下载器中间件
        """
        
        def process_request(self, request, spider):
            # 如果spider为SeleniumSpider的实例,并且request为SeleniumRequest的实例
            # 那么该Request就认定为需要启用selenium来进行渲染html
            if isinstance(spider, SeleniumSpider) and isinstance(request, SeleniumRequest):
                # 控制浏览器打开目标链接
                browser.get(request.url)
                
                # 在构造渲染后的HtmlResponse之前,做一些事情
                #1.比如等待浏览器页面中的某个元素出现后,再返回渲染后的html;
                #2.比如将页面切换进iframe中的页面;
                spider.selenium_func(request)
                
                # 获取浏览器渲染后的html
                html = browser.page_source
                
                # 构造Response
                # 这个Response将会被你的爬虫进一步处理
                return HtmlResponse(url=browser.current_url, request=request, body=html.encode(), encoding="utf-8")
    

    这里要说一下下载器中间件的process_request方法,当每个request通过下载中间件时,该方法被调用。

    1. process_request() 必须返回其中之一: 返回 None 、返回一个 Response 对象、返回一个 Request 对象或raise IgnoreRequest 。
    2. 如果其返回 Response 对象,Scrapy将不会调用 任何 其他的 process_request() 或 process_exception() 方法,或相应地下载函数; 其将返回该response。 已安装的中间件的 process_response() 方法则会在每个response返回时被调用。

    更详细的关于下载器中间件的资料 -> https://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/downloader-middleware.html#id2

    3.4 额外的工具

    眼尖的读者可能注意到SeleniumSpider类里有个selenium_func方法,并且在SeleniumDownloaderMiddleware的process_request方法返回Resposne之前调用了spider的selenium_func方法

    这样做的好处是,我们可以在构造渲染后的HtmlResponse之前,做一些事情(比如…那种…很骚的那种…你懂的)

    1. 比如等待浏览器页面中的某个元素出现后,再返回渲染后的html;
    2. 比如将页面切换进iframe中的页面,然后返回iframe里面的html(够骚吗);

    等待某个元素出现,然后再返回渲染后的html这种操作很常见的,比如你访问一篇文章,它的正文是ajax加载然后js添加到html里的,ajax是需要时间的,但是selenium并不会等待所有请求都完毕后再返回

    解决方法:

    1. 您可以通过browser.implicitly_wait(30),来强制selenium等待30秒(无论元素是否加载出来,都必须等待30秒)
    2. 可以通过等待,直到某个元素出现,然后再返回html

    所以笔者对<等待某个元素出现>这一功能做了进一步的封装,代码如下

    #!usr/bin/env python  
    # -*- coding:utf-8 _*-
    """ 
    @author:Joshua 
    @description:
    """
    import functools
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    
    def waitFor(browser, select_arg, select_method, timeout=2):
        """
        阻塞等待某个元素的出现直到timeout结束
    
        :param browser:浏览器实例
        :param select_method:所使用的选择器方法
        :param select_arg:选择器参数
        :param timeout:超时时间
        :return:
        """
        element = WebDriverWait(browser, timeout).until(
            EC.presence_of_element_located((select_method, select_arg))
        )
    
    
    # 用xpath选择器等待元素
    waitForXpath = functools.partial(waitFor, select_method=By.XPATH)
    
    # 用css选择器等待元素
    waitForCss = functools.partial(waitFor, select_method=By.CSS_SELECTOR)
    

    waitForXpath与waitForCss 是waitFor函数的两个偏函数,意思这两个偏函数是设置了select_method参数默认值的waitFor函数,分别应用不同的选择器来定位元素

    4. 中间件当然要在settings中激活一下

    在这里插入图片描述

    在我们scrapy项目的settings文件中的DOWNLOADER_MIDDLEWARES字典中添加到适当的位置即可

    5. 使用示例

    5.1一个完整的爬虫示例

    # -*- coding: utf-8 -*-
    """
    @author:Joshua
    @description:
        整合selenium的爬虫示例
    """
    import scrapy
    from my_project.requests import SeleniumRequest
    from my_project.spider import SeleniumSpider
    from my_project.tools import waitForXpath
    
    
    # 这个爬虫类继承了SeleniumSpider
    # 在爬虫跑起来的时候,将启动一个浏览器
    class SeleniumExampleSpider(SeleniumSpider):
        """
        这一网站,他的列表页是静态的,但是内容页是动态的
        所以,用selenium试一下,目标是扣出内容页的#content
        """
        name = 'selenium_example'
        allowed_domains = ['pingdingshan.hngp.gov.cn']
        url_format = 'http://pingdingshan.hngp.gov.cn/pingdingshan/ggcx?appCode=H65&channelCode=0301&bz=0&pageSize=20&pageNo={page_num}'
    
        def start_requests(self):
            """
            开始发起请求,记录页码
            """
            start_url = self.url_format.format(page_num=1)
            meta = dict(page_num=1)
            # 列表页是静态的,所以不需要启用selenium,用普通的scrapy.Request就可以了
            yield scrapy.Request(start_url, meta=meta, callback=self.parse)
    
        def parse(self, response):
            """
            从列表页解析出正文的url
            """
            meta = response.meta
            all_li = response.css("div.List2>ul>li")
    
            # 列表
            for li in all_li:
                content_href = li.xpath('./a/@href').extract()
                content_url = response.urljoin(content_href)
                # 内容页是动态的,#content是ajax动态加载的,所以启用一波selenium
                yield SeleniumRequest(url=content_url, meta=meta, callback=self.parse_content)
    
            # 翻页
            meta['page_num'] += 1
            next_url = self.url_format.format(page_num=meta['page_num'])
            # 列表页是静态的,所以不需要启用selenium,用普通的scrapy.Request就可以了
            yield scrapy.Request(url=next_url, meta=meta, callback=self.parse)
    
        def parse_content(self, response):
            """
            解析正文内容
            """
            content = response.css('#content').extract_first()
            yield dict(content=content)
          
        def selenium_func(self, request):
            # 这个方法会在我们的下载器中间件返回Response之前被调用
            
            # 等待content内容加载成功后,再继续
            # 这样的话,我们就能在parse_content方法里应用选择器扣出#content了
            waitForXpath(self.browser, "//*[@id='content']/*[1]")
    
    

    5.2 更骚一点的操作…

    假如内容页的目标信息处于iframe中,我们可以将窗口切换进目标iframe里面,然后返回iframe的html

    要实现这样的操作,只需要重写一下SeleniumSpider子类中的selenium_func方法

    要注意到SeleniumSpider中的selenium_func其实是啥也没做的,一个pass,所有的功能都在子类中重写

    def selenium_func(self, request):
        # 找到id为myPanel的iframe
        target = self.browser.find_element_by_xpath("//iframe[@id='myPanel']")
        # 将浏览器的窗口切换进该iframe中
        # 那么切换后的self.browser的page_source将会是iframe的html
        self.browser.switch_to.frame(target)
    

    6. selenium的一些替代(一些解决动态页面别的方法)

    1. scrapy官方推荐的scrapy_splash
      • 优点
        • 是异步的
        • 可以将部署scrapy的服务器与部署splash的服务器分离开
        • 留给读者遐想的空间
      • 本人觉得的缺点
        • 喂喂,lua脚本很麻烦好吗…(大牛请别打我)
    2. 最新的异步pyppeteer操控浏览器
      • 优点
        • 调用浏览器是异步的,操控的单位是tab页,速度更快
        • 留给读者遐想的空间
      • 本人觉得的缺点
        • 因为pyppeteer是python版puppeteer,所以puppeteer的一些毛病,pyppeteer无可避免的完美继承
        • 笔者试过将pyppeteer整合至scrapy中,在异步中,scrapy跑起来爬虫,总会偶尔timeout之类的…

    anyway,上面两个都是不错的替代,有兴趣的读者可以试一波

    7. scrapy整合selenium的一些缺点

    1. selenium是阻塞的,所以速度会慢些
    2. 对于一些稍微简单的动态页面,最好还是自己去解析一下接口,不要太过依赖selenium,因为selenium带来便利的同时,是更多资源的占用
    3. 整合selenium的scrapy项目不宜大规模的爬取,比如你在自己的机子上写好了一个一个的爬虫,跑起来也没毛病,速度也能接受,然后你很开心地在服务器上部署了你项目上的100+个爬虫(里面有50%左右的爬虫启用了selenium),当他们跑起来的时候,服务器就原地爆炸了… 为啥? 因为相当于服务器同时开了50多个浏览器在跑,内存顶不住啊(土豪忽略…)
    展开全文
  • (1)Scrapy模块安装 scrapy支持Python2.7和python3.4以上版本。 python包可以用全局安装(也称为系统范围),也可以安装在用户空间中。 Windows 一.直接安装 1.在https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载...

    (1)Scrapy模块安装

    scrapy支持Python2.7和python3.4以上版本。

    python包可以用全局安装(也称为系统范围),也可以安装在用户空间中。

    Windows
    一.直接安装
    1.在https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载对应的Twisted的版本文件
    2. 在命令行进入到Twisted的目录 执行pip install 加Twisted文件名

    3.执行pip install scrapy
    二.annaconda 下安装 (官方推荐)
    1.安装conda
    conda旧版本 https://docs.anaconda.com/anaconda/packages/oldpkglists/
    安装方法 https://blog.csdn.net/ychgyyn/article/details/82119201
    2. 安装scrapy conda install scrapy

    (2)Scrapy框架简介

    Scrapy是纯Python开发的一个高效,结构化的网页抓取框架。

    Scrapy是个啥?

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。 Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试 Scrapy使用了Twisted 异步网络库来处理网络通讯。

    我们为啥要用这玩意呢&

    展开全文
  • DOWNLOADER_MIDDLEWARES = { 'scrapy_test.middlewares.RandomUserAgent': 100, }
  • scrapy简单使用

    万次阅读 2018-10-16 16:25:36
    进入虚拟环境,pip install scrapy 2.创建新项目 执行:scrapy startproject Tencent , 会在当前目录下创建一个Tencent项目文件 3.创建爬虫 可手动创建 ,也可通过指令 : cd Tencent , scrapy crawl tencent ...
  • 先来看个小案例:使用scrapy爬取百度图片。( 目标百度图片URL: https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&sf=1&fmq=&pv=&ic...
  • Scrapy爬虫框架,入门案例(非常详细)

    万次阅读 多人点赞 2020-03-21 15:44:49
    Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试. 其最初是为了页面抓取 (更确切来说, 网络抓取 ...
  • Scrapy 学习

    万次阅读 2020-12-29 18:00:29
    文章目录一、概述二、Scrapy五大基本构成:三、整体架构图四、Scrapy安装以及生成项目五、日志等级与日志保存六、导出为json或scv格式七、一个完整的案例 一、概述 Scrapy,Python开发的一个快速、高层次的屏幕抓取和...
  • Scrapy使用隧道代理403问题解决方案

    万次阅读 2021-02-03 16:18:08
    Scrapy使用隧道代理访问HTTPS网站不换IP排查 客户现象 快代理隧道代理客户反馈使用隧道代理没有换IP,原因是使用了隧道代理但是目标网站还是403,跳验证码屏蔽等等,用户推断隧道没有更换代理IP 反爬研究 询问用户...
  • 学习Python的爬虫框架Scrapy,框架函数讲解,非常详细,零基础入门
  • scrapy 常用命令详解

    万次阅读 2020-06-07 18:14:26
    官方文档:https://docs.scrapy.org/en/latest/topics/commands.html Global commands: startproject genspider settings runspider shell fetch view version Project-...
  • scrapy_properties scrapy学习
  • python scrapy 爬虫基础 分布式爬虫 scrapy python scrapy 爬虫基础 分布式爬虫 scrapy
  • scrapy-redis分布式爬虫框架+示例
  • Learning Scrapy

    2016-06-30 16:54:20
    Learning Scrapy
  • scrapy教程

    2016-06-13 20:36:40
    scrapy教程
  • scrapy 实例 一些scrapy实例
  • Scrapy 2.0

    万次阅读 2020-03-25 11:04:49
    Scrapy 2.0 Scrapy 安装 (scrapy) C:\Users\15011>pip install scrapy -i https://pypi.douban.com/simple/ 如果遇到安装Twisted包的时候,报出以下错误。 Building wheels for collected packages: Twisted ...
  • 爬虫 第六讲 Scrapy框架

    万次阅读 2021-04-29 16:00:03
    爬虫 第六讲 Scrapy框架 一、Scrapy框架初级 Scrapy介绍 什么是Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取 Scrapy使用了Twisted异步网络...
  • [Scrapy使用技巧] 如何在scrapy中捕获并处理各种异常

    万次阅读 多人点赞 2018-06-15 16:29:50
    使用scrapy进行大型爬取任务的时候(爬取耗时以天为单位),无论主机网速多好,爬完之后总会发现scrapy日志中“item_scraped_count”不等于预先的种子数量,总有一部分种子爬取失败,失败的类型可能有如下图两种...
  • 如果您需要Scrapy的浏览器集成,请考虑使用 Scrapy的Pyppeteer集成 该项目提供了一个Scrapy下载处理程序,该处理程序使用执行请求。 它可用于处理需要JavaScript的页面。 该软件包不会干扰常规的Scrapy工作流程,...
  • 1 scrapy 安装 1.1 scrapy 安装 进入 cmd 界面,使用命令: pip install scrapy 1.2 安装问题 如果因为权限原因导致安装失败,就以管理员身份运行 cmd,再使用上面的命令。 如果出现 Microsoft Visual C++14.0 is ...
  • scrapy爬虫框架课程,包含全部课件与代码课程纲要:1.scrapy的概念作用和工作流程2.scrapy的入门使用3.scrapy构造并发送请求4.scrapy模拟登陆5.scrapy管道的使用6.scrapy中间件的使用7.scrapy_redis概念作用和流程8....
  • Scrapy爬虫

    2017-04-16 15:04:56
    Scrapy使用IP池,通过爬虫自动获取IP。
  • 安装scrapy:执行 pip install scrapy 【注】安装完成后,执行 pip list 检查以下上述两个模块是否安装成功。 三、在pycharm创建一个Scrapy项目 1.在pycharm中创建一个普通项目(Pure Project 即可),如下图。 2...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 84,231
精华内容 33,692
关键字:

scrapy