scrapy基础学习(未完待续)

本文详细介绍了Scrapy框架的核心组件,包括ScrapyEngine、Scheduler、Downloader、Spider、Middleware等,并探讨了Selector、XPath、CSS选择器和正则表达式的使用。此外,还涉及了Selenium在处理异步加载页面的应用,Mongodb的数据存储,以及分布式爬虫的基本概念。文章推荐了几本Scrapy和Python爬虫领域的经典书籍,帮助读者深入学习。
摘要由CSDN通过智能技术生成
scrapy部件
  • ScrapyEngine:核心 负责工作。。。
  • Scheduler:调度负责处理request请求
  • Downloader:根据请求下载,得到respose
  • Spider:分解response(下载下来的东西),得到数据和链接
  • DownloaderMiddleware:下载中间件,自定义拓展功能(请求和反馈进行预处理),一个中间件完成一个功能
  • SpiderMiddleware:拓展spider(请求和反馈进行预处理)
  • ItemPipline:详细处理分析清洗数据(打包处理好数据)

在这里插入图片描述

scrapy文件及函数理解

  • spiders.py:包含爬虫文件,以下是爬虫类中的方法和变量
    • name ,它是每个项目唯一的名字,用来区分不同的 Spider,爬虫文件里可以有很多个类,如果我们要再写多一个spider, 可以用
#domain 域名
scrapy genspider [options] name domain
#不用手动配置相关的。。
  • allowed_domains ,它是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过虑掉
  • 其中的parse函数用来处理response,提取数据,提交item,还能翻页
  • start_urls,url列表
  • custom settings 它是 个字典,是专属于本 Spider 的配置,此设置会覆盖项目全局的设
    此设置必须在初始化前被更新,必须定义成类变量
  • crawler:它是由 from_crawler()方法设置的,代表的是本Spider 类对应的Crawler 对象Crawer 对象包含了很多项目组件,利用它我们可以获取项目的 些配置信息,如最常见的获取项目的设置信息,即Settings
  • settings: 它是 Settings对象,利用它我们可以直接获取项目的全局设置变量,除了基础属性,Spider还有些常用的方法
  • start_requests(): 此方法用于生成初始请求,它必须返回一个可迭代对象 此方法会默认
    使用 start_urls 里面的URL 来构造 Request ,而 Request是GET请求方式 如果我们想在启
    动时以 POST 方式访问某个站点,可以直接重写这个方法,发送 POST 请求时使用 FormRequest即可
  • closed() :Spider 关闭时,该方法会被调用
  • middlewares.py:定义Spider Middlewares 和Downloader Middlewares的实现
  • Downloader Middlewares:函数略
    自定义的 Downloader Middleware 要添加到项目里, DOWNLOADER_MIDDLEWARES_BASE 变量不能直接修改,修改变量DOWNLOADER_MIDDLEWARES ,向其中添加自定义的 Downloade Middleware ,以及禁用 DOWNLOADER MIDDLEWARES BASE 的定义
  • 修改请求时的user_agent:在settings里面添加user_agent或用process_request()方法

在settings.py中添加

MY_USER_AGENT = [可用的User-Agent]

在middlewares.py文件中添加

import scrapy
from scrapy import signals
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
import random
class MyUserAgentMiddleware(UserAgentMiddleware):    #  继承自UserAgentMiddleware
    '''
    设置User-Agent
    '''
    def __init__(self, user_agent):
        self.user_agent = user_agent

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            user_agent=crawler.settings.get('MY_USER_AGENT')     #   从settings里面取出USER_AGENT列表
        )

    def process_request(self, request, spider):
        agent = random.choice(self.user_agent)
        request.headers['User-Agent'] = agent
        #    添加到headers里面,最后默认返回None

将自定义的MyUserAgentMiddleware类添加到DOWNLOADER_MIDDLEWARES

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddleware.useragent.UserAgentMiddleware': None, 
    'myproject.middlewares.MyUserAgentMiddleware': 400,
}
  • Spider Middlewares同上

  • Items.py:

    • 定义item数据结构,就像一个字典,不过使用的时候要实例化
    • 继承 scrapy.Item 类,并且定义类型为 scrapy.Field 字段
  • settings.py:定义项目的全局配置

  • 以下是简单理解(其实我对它很好奇)

 BOT_NAME = 'xiaozhu'  项目名称
    SPIDER_MODULES = ['xiaozhu.spiders']  爬虫文件路径
    NEWSPIDER_MODULE = 'xiaozhu.spiders'
    Crawl responsibly by identifying yourself (and your website) on the user-agent
    设置模拟浏览器加载
    USER_AGENT = 'qidianwang (+http://www.yourdomain.com)'

    Obey robots.txt rules
    是否遵守robot协议(默认为True表示遵守)
    ROBOTSTXT_OBEY = False
    Configure maximum concurrent requests performed by Scrapy (default: 16)   
   ? scrapy 发起请求的最大并发数量(默认是16个)
    CONCURRENT_REQUESTS = 32
    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
    设置下载延时,默认为0
    DOWNLOAD_DELAY = 0
    The download delay setting will honor only one of:
    在每个域下允许发起请求的最大并发数(默认是8个)
    CONCURRENT_REQUESTS_PER_DOMAIN = 16
    针对每个ip允许发起请求的最大并发数量(默认0个)
    1.在不为0的情况CONCURRENT_REQUESTS_PER_IP的设置优先级要比CONCURRENT_REQUESTS_PER_DOMAIN要高
    2.不为0的情况下DOWNLOAD_DELAY就会针对于ip而不是网站了,
    CONCURRENT_REQUESTS_PER_IP = 16
    Disable cookies (enabled by default)
    是否要携带cookies,默认为True表示携带
    COOKIES_ENABLED = False
    COOKIES_DEBUG 默认为False表示不追踪cookies
    COOKIES_DEBUG = True
    Disable Telnet Console (enabled by default)
      ====是一个扩展插件,通过TELENET可以监听到当前爬虫的一些状态,默认是True开启状态
    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',
    'User-Agnet':'Mozilla/5.0 (X11; Linux x86_64)          AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',

   }
   Enable or disable spider middlewares
   See https://doc.scrapy.org/en/latest/topics/spider-middleware.html

    爬虫中间件
   SPIDER_MIDDLEWARES = {
   'qidianwang.middlewares.QidianwangSpiderMiddleware': 543,
      }
    Enable or disable downloader middlewares
    See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html

    下载中间件,自定义下载中间键需要在这里激活,后面的数字越小优先级越高,
    DOWNLOADER_MIDDLEWARES = {
    'qidianwang.middlewares.QidianUserAgentDownloadmiddlerware': 543,
   'qidianwang.middlewares.QidianProxyDownloadMiddlerware':544,**
    'qidianwang.middlewares.SeleniumDownlaodMiddlerware':543,
   }
     Enable or disable extensions
      See https://doc.scrapy.org/en/latest/topics/extensions.html

       EXTENSIONS================添加扩展
       EXTENSIONS = {
       'scrapy.extensions.telnet.TelnetConsole': None,
        }
      Configure item pipelines
      See https://doc.scrapy.org/en/latest/topics/item-pipeline.html

      激活管道,后面跟的数字越小优先级越高
       ITEM_PIPELINES = {
      'qidianwang.pipelines.QidianwangPipeline': 300,
      'scrapy_redis.pipelines.RedisPipeline': 400,
       }
      动态下载延时,(自动限速的扩展,默认情况下是关闭的)
      使用步骤1.打开:AUTOTHROTTLE_ENABLED = True
      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:
     是否要开启自动限速的DEBUG模式
     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 = False)
     HTTPCACHE_ENABLED = True
     =====设置缓存超时的时间
     HTTPCACHE_EXPIRATION_SECS = 0
     =====设置缓存保存的路径
     HTTPCACHE_DIR = 'httpcache'
     =====缓存忽略的响应状态码设置为400表示忽略掉不缓存 :                                                      HTTPCACHE_IGNORE_HTTP_CODES = ['400']
     HTTPCACHE_IGNORE_HTTP_CODES = []
     缓存的储存插件,
     HTTPCACHE_STORAGE =  'scrapy.extensions.httpcache.FilesystemCacheStorage'
     将log日志信息保存在本地文件
     LOG_FILE = 'qdlogfile.log'
     LOG_LEVEL = 'DEBUG'
  • pipelines.py:定制与激活Itempipeline,对数据进行处理(比如限制或增删),进而存储数据(mongodb,mysql)
  • process_item():
    Item Pipeline 会自动调用这个方法,该方法必须返回包含数据的字典或 Item对象,或者抛出 Dropltem 异常
    参数: 一个是 item ,每次 Spider 生成的 Item 都被传递
    另一个是 spider ,就是spider 实例
  • open_spider 当spider 开启时,这个方法被调用
  • close_spider 当spider关闭时,这个方法会调用
  • from_crawler 它是一个类方法,用@class method 标识, 是一种依赖注入的方式 它的参数就是 crawler ,通过 crawler 我们可以拿到全局配置的每个配置信息 在全局配置 settngs.py中,我们可以定义 MONGO_URI MONGO_DB 来指定 MongoDB 接需要的地址和数据库名称。拿到配置信息之后返回 对象即可 所以这个方法的定义主要是用来获取 settings.py 中的配置的

def __init__(self,mongo_url,mongo_db):
	self.mongo_url = mongo_url
	self.mongo_db = mongo_db

@classmethod
def from_crawler(cls, crawler):
    return els(
mongo_uri=crawler.settings.get('MοNGO_URI ’),
mongo_db=crawler.settings.get(’ MONGO_DB') 
)
  • scrapy.cfg:配置scrapy项目文件路径,部署相关信息

学习与理解:selector与scrapy shell与xpath与css与正则

  • 选择器:选择元素的一种方式,不同的选择其实用不同的方法

  • selector:可以脱离scrapy单独使用,一个强大的网页解析库
    body= '<html><head><title>Hello World</title></head><body></body></ html> ’ selector = Selector(text=body)生成了一个Selector 选择器对象

  • xpath:response .xpath () 是scrapy中对response.selector.xpath ()方法设置的快捷方式,得到Selectorlist 类型的变量, 由 Selector 对象组成的列表

  • xpath非常好用,跟正则搭配很完美

selenium

对于异步加载,一方面可以分析ajax找到对应的接口抓取,也可以用selenium或splash模拟浏览器
代码案例(对代码还没有完全理解)

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from scrapy.http import HtmlResponse
from logging import getLogger


class SeleniumMiddleware(object):
    def __init__(self, timeout=None, service_args=[]):
        self.logger = getLogger(__name__)
        self.timeout = timeout    # 设置页面超时时间
        self.browser = webdriver.PhantomJS(service_args=service_args)
        self.browser.set_window_size(1400, 700)   # 设置页面大小
        self.browser.set_page_load_timeout(self.timeout)
        self.wait = WebDriverWait(self.browser, self.timeout)
    
    def __del__(self):
        self.browser.close()
    
    def process_request(self, request, spider):
        """
        用PhantomJS抓取页面
        :param request: Request对象
        :param spider: Spider对象
        :return: HtmlResponse
        """
        self.logger.debug('PhantomJS is Starting')
        page = request.meta.get('page', 1)
      
        try:    #    调用 PhantomJS 对象的 get ()方法访问 Request 的对应的 URL ,相当于
Request 对象里获取请求链接,然后再用 PhantomJS 加载,不再使用 Scrapy 里的 Downloader
            self.browser.get(request.url)
            if page > 1:
                input = self.wait.until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager div.form > input')))
                submit = self.wait.until(
                    EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager div.form > span.btn.J_Submit')))
                input.clear()
                input.send_keys(page)
                submit.click()
            self.wait.until(
                EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager li.item.active > span'), str(page)))
            self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item')))
            return HtmlResponse(url=request.url, body=self.browser.page_source, request=request, encoding='utf-8',
                                status=200)
        except TimeoutException:
            return HtmlResponse(url=request.url, status=500, request=request)
    
    @classmethod
    def from_crawler(cls, crawler):
        return cls(timeout=crawler.settings.get('SELENIUM_TIMEOUT'),
                   service_args=crawler.settings.get('PHANTOMJS_SERVICE_ARGS'))


settings.py里设置
DOWNLOADER_MIDDLEWARES = {
"scrapyseleniumtest.middlewares.SeleniumMiddleware": 543, 
}

Mongodb储存

Item Pipeline里

import pymongo


class MongoPipeline(object):
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db
    
    @classmethod
    def from_crawler(cls, crawler):
        return cls(mongo_uri=crawler.settings.get('MONGO_URI'), mongo_db=crawler.settings.get('MONGO_DB'))
    
    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]
    
    def process_item(self, item, spider):
        self.db[item.collection].insert(dict(item))
        return item
    
    def close_spider(self, spider):
        self.client.close()


settings.py 添加
# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {    #  开启这个类的调用
    'scrapyseleniumtest.pipelines.MongoPipeline': 300,
}
MONGO_URI = 'localhost'
MONGO_DB = 'taobao'
#注明这两个

分布式爬虫

  • 单爬虫

  • 单机限制于网络速度

  • IO吞吐量 网线限制

  • 多爬虫问题

  • 数据共享:同步

  • 自动分工机制,充分利用资源提高效率

  • Redis功能(内存数据库,同时保存到硬盘):

  • 安装(略)

  • 内容保存数据库:Mongdb,Mysql等(运行在内存,数据保存在硬盘?,控制保存时间)

  • 简单原理理解

  • 由Redis管理请求队列(排重保存),scrapy自己的请求队列就不再使用(在settings里面设置队列为远程)

学习推荐(成为爬虫专家必读)
  • Python爬虫开发与项目实战(范传辉,机械工业)
  • 精通Python爬虫框架scrapy(李斌译,人民邮电)
  • 崔庆才
内存数据库的简单理解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值