安装scrapy

安装scrapy:

1.pip3 install wheel
2.下载twisted  网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted  如下图
3.cmd进入你所下载文件的目录,pip3 install 你下的文件名
4.pip3 install pywin32
5.pip3 install scrapy

大功告成!!!

image-20210608161820557

创建scrapy项目

# 1. 在终端敲入命令:scrapy startproject 项目名  
# 2. cd 进你所创建的项目中  (这样第三步所创建的文件会自动加入进项目中的spider目录中)
# 3. 创建爬虫文件:scrapt genspider 文件名 url
# 文件内容
	import scrapy
    class FirstSpider(scrapy.Spider):
        # 爬虫文件的名称:根据名称可以定位到指定的爬虫文件
        name = 'first'
        # 允许的域名
        # allowed_domains = ['www.baidu.com']  # 一般会将其注释
        # 起始的url列表
        start_urls = ['https://www.baidu.com/']  # 创建文件时所写的起始url

        def parse(self, response):
            print(response)
# 4. 运行文件:scrapy crawl 文件名 【--nolog】不写时运行会出现log日志

第一次运行scrapy问题

# 第一次运行如果写了 --nolog不会出现结果
# 问题;第一种反爬机制 -- robots.txt
# 解决方法:在settings文件中修改配置  ROBOTSTXT_OBEY = False

配置UA

去所创建项目的settings.py配置
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'

爬虫文件的返回值(response)

# parse方法的response是请求返回的返回值
div_list = response.xpath('')  #  div_list为一个列表对象,每一个元素为Selector对象

# 不过用法与lxml中etree.xpath用法一致
提取Selector的文本
1.xpath('//xx/x/text()').extract() # 该方法会将列表中所有的Selector中的文本全部提取
2.xpath('//xx/x/text()').extract_first() # 该方法会将列表中第一个Selector中的文本提取

持久化存储

  1. 步骤:

image-20210611164533951

# 注意:默认情况下,管道机制并没有开启.需要手动在配置文件中进行开启

# 使用管道进行持久化存储的流程:
# 1.获取解析到的数据值
# 2.将解析的数据值存储到item对象(item类中进行相关属性的声明)
# 3.通过yild关键字将item提交到管道
# 4.管道文件中进行持久化存储代码的编写(process_item)
# 5.在配置文件中开启管道
一.基于终端命令进行存储
	# 基于终端指令的持久化存储:可以通过终端指令的形式将parse方法的返回值中存储的数据进行本地磁盘的持久化存储
    # return all_data
    '''在终端运行文件 :scrapy crawl 爬虫文件名 -o(存储文件命令)  xx.txt(不能存储为txt形式,可以先运行此命令,系统会提示可以将数据存储为何种形式)'''  如上图所示
    
二.基于数据库存储
    item.py:
        class BossproItem(scrapy.Item):
         '''define the fields for your item here like:
            name = scrapy.Field()
            title = scrapy.Field()
            salary = scrapy.Field()
            company = scrapy.Field()
         '''
        
    爬虫文件:实例化一个BossproItem对象
    		# item = BossproItem()
        	# item['xx'] = 所爬取的数据  xx为item中所定义的字段
           	....
            #将item对象提交给管道进行持久化存储
            yield item  # 包含你想要存储的数据  发送给pipelines.py
    
   pipelines.py:
    		如下图⬇⬇⬇⬇
        重写父类的方法:open_spider(self,spider)与close_spider(self,spider)
        # spider为你创建的爬虫文件对象
       

基于文件存储

image-20210611165847747

基于mysql存储

image-20210611170138587

基于Redis存储

image-20210611170254041

# 一定记得开启管道!!!

image-20210611171223237

scrapy的cookie处理

我们知道,一些网站的进入需要cookie
例如:QQ空间的登录等...如果我们爬虫需要模拟登录后需要拿到详情页面,需要携带cookie, 那么scrapy是如何处理cookie?
在一般情况下,我们会在登录后通过请求头拿到cookie,然后将cookie加入进headers中,然后拿到用户详情页面数据
scrapy不需要,只需要将配置修改  初始是注释(自动处理cookie),如果你发送请求时scrapy会携带cookie,不需要我们主动去获取cookie
			是不是很方便啊

image-20210611173953529

scrapy发送post请求

image-20210611171956176

# FormRequest可以发送post请求
# 该方法的formdata接收发送的数据,数据类型为字典

scrapy请求传参

 # 当使用scrapy进行数据爬取的时候,如果发现爬取的数据值没有在同一张页面中进行存储.则必须使用请求传参进行处理(持久化)
	#  将item实例化的对象作为全局变量会出点小问题 (值有些会被覆盖)
    #  scrapy.Request方法或scrapy.FormRequest方法中的meta可以传参,meta为一个字典类型
    #  接收时可以用response.meta接收然后赋给一个变量

image-20210611172728961

提升爬取的效率

通常,我们使用多线程可以提升效率

scrapy可以通过修改配置提升爬取的效率

修改配置:
# 增加并发:
# 默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。
CONCURRENT_REQUESTS = 10

# 降低日志级别:
#     在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:
LOG_LEVEL = ‘INFO’   LOG_LEVEL = 'ERROR'

# 禁止cookie:
# 如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写: 
COOKIES_ENABLED = False

# 禁止重试:
#     对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:
RETRY_ENABLED = False

# 减少下载超时:
#     如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:
DOWNLOAD_TIMEOUT = 10 超时时间为10s

UA池与代理池

先了解scrapy的框架

https://www.jianshu.com/p/8e78dfa7c368

image-20210611175732176

看代码吧(说不太清,或者看书)

CrawlSpider

'crawlspider是Spider的派生类(一个子类),Spider类的设计原则是只爬取start_url列表中的网页,而CrawlSpider类定义了一些规则(rule)来提供跟进link的方便的机制,从爬取的网页中获取link并继续爬取的工作更适合。'

crawlspider的使用

https://www.jianshu.com/p/a6a08b4f7c04

一.创建项目: scrapy startsproject 项目名
   cd 项目名
   创建爬虫文件:scrapy genspider -t crawl 文件名  起始url(www.xxx.com)

例 :如下为创建的爬虫文件

# -*- coding: utf-8 -*-
import scrapy
# 导入CrawlSpider相关模块
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

# 表示该爬虫程序是基于CrawlSpider类的
class CrawldemoSpider(CrawlSpider):
    name = 'crawlDemo'    #爬虫文件名称
    #allowed_domains = ['www.qiushibaike.com']
    start_urls = ['http://www.qiushibaike.com/']
    
    #连接提取器:会去起始url响应回来的页面中提取指定的url
    link = LinkExtractor(allow=r'/8hr/page/\d+')
    #rules元组中存放的是不同的规则解析器(封装好了某种解析规则)
    rules = (
        #规则解析器:可以将连接提取器提取到的所有连接表示的页面进行指定规则(回调函数)的解析
        Rule(link, callback='parse_item', follow=True),
    )
    # 解析方法
    def parse_item(self, response):
        # print(response.url) 返回的是相似的url
        divs = response.xpath('//div[@id="content-left"]/div')
        for div in divs:
            author = div.xpath('./div[@class="author clearfix"]/a[2]/h2/text()').extract_first()
            print(author)

<!-- CrawlSpider类和Spider类的最大不同是CrawlSpider多了一个rules属性,其作用是定义”提取动作“。在rules中可以包含一个或多个Rule对象,在Rule对象中包含了LinkExtractor对象。 -->

分布式爬虫

-- 为了加快数据的爬取效率

步骤一.
	1.安装模块:pip3 install redis_scrapy
	2.创建项目 scrapy startsproject 项目名
	cd 项目名
	3.创建爬虫文件:scrapy genspider 文件名 起始url(www.xxx.com)
步骤二.修改爬虫文件
    1.导入scrapy_redis模块: from scrapy_redis.spiders import RedisSpider
    2.将当前爬虫的父类修改成 RedisSpider
    3.将allowed_domains和start_urls注释(分布式,不能每一个爬虫文件都有一个起始url)
    4.添加一个新的属性 redis_key = "xxx",该属性表示的是可以被共享的调度器队列的名称
步骤三.修改配置文件(settings.py)
    1.保证爬虫文件所提交的请求都会被提交到共享的调度器的队列中
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    2.保证爬虫文件提交的item会被提交到共享的管道中
    ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 400
    }
    3.配置最终数据存储的redis数据库
    REDIS_HOST = 'redis服务的ip地址'
    REDIS_PORT = 6379
    REDIS_ENCODING = ‘utf-8’
    REDIS_PARAMS = {‘password’:’123456’}
    4.redis数据库的配置文件进行配置:关闭保护模式和注释掉bind 127.0.0.1
    5.开启redis服务和客户端
    6.执行爬虫文件:scrapy runspider xxx.py
    7.向调度器队列中仍入一个起始的url:
        # 进入redis-cli中:lpush key value
        # key为redis_key
        # value为起始url
        
settings中加入如下配置:       
    # 使用的是可以被共享的调度器
    # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 使用scrapy-redis组件自己的调度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
    SCHEDULER_PERSIST = True
    
 运行文件:
	***切换到spider目录下,运行命令:
    	scrapy runspider 爬虫文件.py
    运行文件后会卡在listen处  --->  等待一个url
    执行步骤三中的第7步,程序将继续向下执行

增量式爬虫

增量式爬虫:每次爬取网站中更新的数据.
定时爬虫:使用脚本在指定时间内进行一次数据(最新更新)的爬取.

爬取数据的流程:
    1.指定url
    2.根据指定的url发请求,获取页面数据
    3.持久化存储

案例:
实现增量式爬虫的方案:
    1.在发送请求之前,判断url之前是否爬取过
        a.将即将进行爬取的数据对应的url存储到redis的set中.
        
    2.根据爬取到的数据进行重复过滤,然后在进行持久化存储
        b.将爬取到的数据给其生成一个唯一的标识(可以将该标识作为mysql的列.可以将该标识存储到redis的set中)

自定义增量式爬虫

将爬取的url或数据进行唯一标识
ex = redis.sadd(key,value)
若ex返回值为1,则该数据将会放入redis数据库中
若返回为0,则说明redis数据库中存在该数据
判断ex的返回值可以进行爬取网页更新的数据


# 看爬虫文件的day07部分

定时爬虫

posted @ 2023-03-05 12:37  w随风w  阅读(55)  评论(0编辑  收藏  举报