返回顶部

爬虫之Scrapy框架介绍及基础用法

今日内容概要

  • 爬虫框架之Scrapy
  • 利用该框架爬取博客园
  • 并发编程

今日内容详细

爬虫框架Scrapy

1.什么是框架?
  框架类似于房子的结构,框架会提前帮你创建好所有的文件和内部环境
  你只需要往对应的文件里面书写对应的代码就可以让该框架帮你运行

1.1简介
     Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓取)所设计的,使用它可以快速、简单、可扩展的方式从网站中提取所需的数据。但是目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。
    Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。整体架构大致如下

    
    
1.2重要组件
    引擎(EGINE)
    引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。

    调度器(SCHEDULER)
    用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
    
    下载器(DOWLOADER)
    用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的
    
    爬虫(SPIDERS)
    SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求
    
    项目管道(ITEM PIPLINES)
    在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作
    
    下载器中间件(Downloader Middlewares)
    位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,你可用该中间件做以下几件事
    process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
    change received response before passing it to a spider;
    send a new Request instead of passing received response to a spider;
    pass response to a spider without fetching a web page;
    silently drop some requests.
    
    爬虫中间件(Spider Middlewares)
    位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)
    
2.下载
	Max、Linux系统
    直接
    pip3 install scrapy即可
  	
    windows系统可以需要以下多个步骤
    先尝试着输入pip3 install scrapy如果不报错那最好
    如果报错的话 需要进行下列多步报错
    https://www.cnblogs.com/Dominic-Ji/p/9550525.html
      
3.验证下载是否成功
	在cmd终端中输入
    	scrapy
    # 下载如果报错 并且是time out仅仅是因为你的网速不稳定导致的
​```

### 基本使用

​```python
		-新建项目
    		自己先切换到你想要创建项目的路径下
			-scrapy startproject 项目名字
		-新建爬虫
			-scrapy genspider 爬虫名 爬取的域名
            # 自动帮你创建一个爬取对应网站的py文件 之后在该文件内书写爬取该网站的代码
		-项目目录介绍
			-spiders
				-所有的爬虫程序  # 一个个的py文件
			-items.py
				-类似于django的model类  # 数据库表/集合相关
                '''
                				ORM的概念
                				对象关系映射
                表					  					  类
                记录					 					 对象
                字段数据			    					对象点属性
                能够让一个不会sql语句的python程序员使用面向对象的代码
                也能够操作数据库
                '''
			-middlewares.py
				-中间件		# 能够帮你执行更多额外的功能 在特定的阶段
			-pipelines.py
				-持久化相关(数据存储)
			-settings.py
				-配置文件(关注:爬虫协议)
                # Obey robots.txt rules
				ROBOTSTXT_OBEY = False  # 在爬取网站的时候一定要把这个配置改为False
			-scrapy.cfg
				-部署相关
		-运行爬虫
        	# 默认是没有启动文件的 只能用命令行运行
			-scrapy crawl cnblogs --nolog  # --nolog运行之后不打印日志相关信息
			# 如果你想要右键利用pycharm帮你运行的话
            在项目文件夹下自己创建一个main.py文件
            from scrapy.cmdline import execute
            execute(['scrapy', 'crawl', 'cnblogs','--nolog'])
            '''列表里面的一个个元素就是完整命令的一个个单词的拆分'''
            
		-爬取数据
			//*[@id="post_list"]/div[1]  # Xpath选择器
​```

### 深度优先、广度优先

​```python
深度优先
	先获取每一个页面里面的链接标签,一直找链接标签
广度优先
	以页面为基准 先爬取该页面所有的数据 之后再去爬第二个页面
​```

### 三种调度策略

​```python
三种调度策略
	深度优先
  	广度优先
  	优先级
 
队列
	先进先出
堆栈
	先进后出
优先级队列
	可控进出
    
"""
scrapy利用了队列的机制来协调管理多任务不冲突的情况
"""
​```

### 持久化

​```python
1 pipeline持久化
		-1 在item中写一个类,有一个一个字段
  			class ArticleItem(scrapy.Item):
              article_name = scrapy.Field()
              article_url = scrapy.Field()
              auther_name = scrapy.Field()
              commit_count = scrapy.Field()
		-2 在setting中配置pipeline
			ITEM_PIPELINES = {
					'myscrapy.pipelines.ArticleMongodbPipeline': 300,   #数字越小越先执行
				   # 'myscrapy.pipelines.ArticleFilePipeline': 100,
				}
		-3 pipelines.py
			from pymongo import MongoClient
			class ArticleMongodbPipeline(object):
    	def process_item(self, item, spider):

        # client = MongoClient('mongodb://localhost:27017/')
        #连接
        client = MongoClient('localhost', 27017)
        #创建article数据库,如果没有叫创建,如果有,叫使用
        db = client['article']
        # print(db)
        #如果有使用articleinfo,如果没有,创建这个表
        article_info=db['articleinfo']

        article_info.insert(dict(item))
        # article_info.save({'article_name':item['article_name'],'aritcle_url':item['article_url']})
        # 如果retrun None ,下一个就取不到item了,取到的就是None
        
# 爬取代码
# -*- coding: utf-8 -*-
import scrapy
from myscrapy.items import ArticleItem
from scrapy import Request
from scrapy.core.scheduler import Scheduler
from scrapy.dupefilters import RFPDupeFilter
class CnblogsSpider(scrapy.Spider):
    name = 'cnblogs'   #爬虫名,必须唯一
    allowed_domains = ['cnblogs.com']   #允许的域名,
    start_urls = ['https://www.cnblogs.com/']  #起始的url
    custom_settings={"BB":"xxxxx"}

    # 爬虫起始入口 start_requests
     def parse_detail(self,response):
         print(len(response.text))


     def parse(self, response):
         div_list=response.css('.post_item')
         for div in div_list:
             url=div.css('.post_item_body a::attr(href)').extract_first()
             article_name=div.css('.titlelnk::text').extract_first()
             auther_name=div.css('.post_item_foot a::text').extract_first()
             commit_count=div.css('.post_item_foot span a::text').extract_first()
             article_item=ArticleItem()
             #把地址存入数据库,yield item对象
             article_item['article_name']=article_name
             article_item['article_url']=url
             article_item['auther_name']=auther_name
             article_item['commit_count']=commit_count
             yield article_item
​```


posted @ 2020-10-01 08:39  Satan—yuan  阅读(157)  评论(1编辑  收藏  举报