当前位置: 首页 > news >正文

爬虫(二)之scrapy框架

 01-scrapy介绍

02-项目的目录结构:

scrapy.cfg   项目的主配置信息。(真正爬虫相关的配置信息在settings.py 文件中)

items.py    设置数据存储模板,用于结构化数据,如:Django的model

pipelines    数据持久化处理

settings.py 配置文件

spiders      爬虫目录,如:创建文件,编写爬虫解析规则

03-配置文件settings.py的配置

# 建议修改:
ROBOTSTXT_OBEY = False  # 默认为True

# 进行身份伪装
USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"

04-创建项目和爬虫文件

# 创建项目
scrapy startproject firstScrapy

#
先切换到项目文件里 cd firstScrapy/ # 然后执行创建 scrapy genspider first www.qiushibaike.com

05-执行

# 执行爬取程序, first 为爬虫文件名称

scrapy crawl first

# 此方式是阻止日志信息的输出
scrapy crawl first  --nolog

06-基于终端指令的持久化存储

持久化存储操作:
a.磁盘文件
    a)基于终端指令
    i.保证parse方法返回一个可迭代类型的对象(存储解析到的页面内容)
    ii.使用终端指令完成数据存储到制定磁盘文件中的操作
    1.scrapy crawl 爬虫文件名称 –o 磁盘文件.后缀
b)基于管道
    i.items:存储解析到的页面数据
    ii.pipelines:处理持久化存储的相关操作
    iii.代码实现流程:
        1.将解析到的页面数据存储到items对象
        2.使用yield关键字将items提交给管道文件进行处理
        3.在管道文件中编写代码完成数据存储的操作
        4.在配置文件中开启管道操作

b.数据库
    a)mysql
    b)redis
    c)编码流程:
        1.将解析到的页面数据存储到items对象
        2.使用yield关键字将items提交给管道文件进行处理
        3.在管道文件中编写代码完成数据存储的操作
        4.在配置文件中开启管道操作

需求:将爬取到的数据值分别存储到本地磁盘、redis数据库、mysql数据。
    1.需要在管道文件中编写对应平台的管道类
    2.在配置文件中对自定义的管道类进行生效操
# 案例:
#
firstScrapy/spiders/first.py # -*- coding: utf-8 -*- import scrapy class FirstSpider(scrapy.Spider): # 爬虫文件的名称name name = 'first' # 允许的域名:只允许爬取当前域名下的页面数据 # allowed_domains = ['www.qiushibaike.com/text/'] # 起始的url:当前工程所要爬取的页面所对应的url # 注意:start_urls 是 allowed_domains 下的页面的url start_urls = ['https://www.qiushibaike.com/text/'] # 解析方法:对获取的页面数据进行指定内容的解析 # response:请求成功后返回的响应对象 # parse 方法的返回值,必须为迭代器 或者为 空None def parse(self, response): # 建议大家用xpath 进行指定内容的解析(框架集成了xpath解析的接口) # 获取段子的内容和作者 div_list = response.xpath('//div[@id="content-left"]/div') # 存储解析到的页面数据 data_list = [] for div in div_list: # xpath解析到的指定内容被存储到 Selector对象 # extract() 该方法可以将 Selector对象 中存储的数据值拿到 # author = div.xpath('./div/a[2]/h2/text()').extract()[0] # extract_first() == extract()[0] author = div.xpath('./div/a[2]/h2/text()').extract_first() content = div.xpath('.//div[@class="content"]/span/text()').extract_first() dict_data = { 'author': author, 'content': content } data_list.append(dict_data) return data_list

 

# 在终端执行命令:(在first爬虫文件下)

scrapy crawl first -o qiubai.csv --nolog

07-基于管道的持久化存储

# 修改配置文件settings.py
# 打开注释
ITEM_PIPELINES = {
   'firstScrapy.pipelines.FirstscrapyPipeline': 300,
}
# firstScrapy/first.py

# -*- coding: utf-8 -*-
import scrapy
from firstScrapy.items import FirstscrapyItem


class FirstSpider(scrapy.Spider):
    # 爬虫文件的名称name
    name = 'first'
    start_urls = ['https://www.qiushibaike.com/text/']

    def parse(self, response):
        # 获取段子的内容和作者
        div_list = response.xpath('//div[@id="content-left"]/div')

        for div in div_list:
            author = div.xpath('./div/a[2]/h2/text()').extract_first()
            content = div.xpath('.//div[@class="content"]/span/text()').extract_first()

            # 1.将解析到的数据值(author和content)存储到items对象中
            item = FirstscrapyItem()
            item['author'] = author
            item['content'] = content

            # 2.将item对象提交给管道
            yield item

 

# firstScrapy/items.py

import scrapy


class FirstscrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author = scrapy.Field()
    content = scrapy.Field()
# firstScrapy/pipelines.py


class FirstscrapyPipeline(object):
    fp = None
    # open_spider 在整个爬虫过程中,该方法只会在开始爬虫的时候,被调用一次!

    def open_spider(self, spider):
        print("开始爬虫")
        self.fp = open('./qiubai_pipe.txt', 'w', encoding='utf-8')

    # 3.在管道文件中编写代码完成数据储存的操作
    # process_item 该方法就可以接受爬虫文件中提交过来的item对象,并且对item对象中存储的页面数据进行持久化存储
    # 参数:item 表示的是 接收到的item对象
    # 每当爬虫文件向管道提交一次item,则该方法就会被执行一次!

    def process_item(self, item, spider):
        # 取出item对象中存储的数据值
        author = item['author']
        content = item['content']

        # 持久化存储
        self.fp.write(author + ':' + content + '\n\n\n')

        return item

    # 只会在爬虫结束的时候,被调用一次!

    def close_spider(self, spider):
        print('爬虫结束!')
        self.fp.close()

08-基于MySQL的持久化存储

# pipelines.py

import pymysql


class FirstscrapyPipeline(object):
    conn = None
    cursor = None

    def open_spider(self, spider):
        print("爬虫开始!")
        # 链接数据库
        self.conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='qiubai')

    # 编写向数据库中存储数据的相关代码

    def process_item(self, item, spider):
        # 1.连接数据库
        # 2.执行sql语句
        sql = 'insert into qiubai values("%s", "%s")' % (item['author'], item['content'])
        self.cursor = self.conn.cursor()
        try:
            self.cursor.execute(sql)

            # 3.提交事务
            self.conn.commit()
        except Exception as e:
            print(e)
            self.conn.rollback()

        # 取出item对象中存储的数据值
        author = item['author']
        content = item['content']

        return item

    def close_spider(self, spider):
        print("爬虫结束!")
        self.cursor.close()
        self.conn.close()

09-基于redis的持久化存储 

# pipelines.py

import redis


class FirstscrapyPipeline(object):
    conn = None
    cursor = None

    def open_spider(self, spider):
        print("爬虫开始!")
        # 链接redis数据库
        self.conn = redis.Redis(host='127.0.0.1', port=6379)

    # 编写向数据库中存储数据的相关代码

    def process_item(self, item, spider):
        dict_data = {
            'author': item['author'],
            'content': item['content'],
        }
        self.conn.lpush('data', dict_data)

        return item

 10-管道的高级操作

# 修改配置文件settings.py

ITEM_PIPELINES = {
   'firstScrapy.pipelines.FirstscrapyPipeline': 300,
   'firstScrapy.pipelines.FirstByFiles': 200,
   'firstScrapy.pipelines.FirstByMysql': 400,
}

 

# 需求:将爬取到的数据值分别存储到本地磁盘、redis数据库、mysql数据。
1.需要在管道文件中编写对应平台的管道类
2.在配置文件中对自定义的管道类进行生效操作

# pipelines.py

import redis
import pymysql


class FirstscrapyPipeline(object):
    conn = None
    cursor = None

    def open_spider(self, spider):
        print("爬虫开始!")
        # 链接redis数据库
        self.conn = redis.Redis(host='127.0.0.1', port=6379)

    # 编写向数据库中存储数据的相关代码

    def process_item(self, item, spider):
        dict_data = {
            'author': item['author'],
            'content': item['content'],
        }
        self.conn.lpush('data', dict_data)

        return item


# 实现将数据值存储到本地磁盘中
class FirstByFiles(object):
    def process_item(self, item, spider):
        print('数据已经写入指定的磁盘文件中')
        return item


class FirstByMysql(object):
    def process_item(self, item, spider):
        print('数据已经写入到MySQL数据库中')

        return item

 11-就多个url的数据爬取

# 解决方案:请求的手动发送
# spider.py/qiubai.py

# -*- coding: utf-8 -*-
import scrapy
from qiubaiByPages.items import QiubaibypagesItem


class QiubaiSpider(scrapy.Spider):
    name = 'qiubai'
    # allowed_domains = ['www.qiushibaike.com/text']
    start_urls = ['https://www.qiushibaike.com/text/']

    # 设计一个通用的url模板
    url = 'https://www.qiushibaike.com/text/page/%d/'
    pageNum = 1

    def parse(self, response):
        div_list = response.xpath('//*[@id="content-left"]/div')

        for div in div_list:
            author = div.xpath('./div[@class="author clearfix"]/a[2]/h2/text()').extract_first()
            content = div.xpath('.//div[@class="content"]/span/text()').extract_first()

            item = QiubaibypagesItem()
            item['author'] = author
            item['content'] = content

            yield item
        # 请求的手动发送
        if self.pageNum <= 13:
            print('爬取了第%s的页面数据!' % self.pageNum)
            self.pageNum += 1
            new_url = format(self.url % self.pageNum)
            # callback 将请求获取的页面数据进行解析
            yield scrapy.Request(url=new_url, callback=self.parse)

 

转载于:https://www.cnblogs.com/pgxpython/p/10011030.html

相关文章:

  • three.js入门系列之视角和辅助线
  • elementui 走马灯图片自适应
  • CSS浮动(一)---Float
  • mode_w
  • war包
  • Js获取操作系统版本 获得浏览器版本
  • [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper
  • Alpha阶段个人总结
  • BZOJ5091: [Lydsy1711月赛]摘苹果【期望DP】
  • RDIFramework.NET V3.3 Web版新增报表管理功能模块-重量级实用功能
  • /etc/skel 目录作用
  • [逆向工程] 二进制拆弹Binary Bombs 快乐拆弹 详解
  • 软工 · BETA 版冲刺前准备(团队)
  • [源码和文档分享]基于C语言的PL0编译器
  • 图-连通性-有向图的强连通分量
  • 【译】JS基础算法脚本:字符串结尾
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 4个实用的微服务测试策略
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • JAVA_NIO系列——Channel和Buffer详解
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • PAT A1017 优先队列
  • php ci框架整合银盛支付
  • React 快速上手 - 07 前端路由 react-router
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vue学习第二天
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 目录与文件属性:编写ls
  • 前端攻城师
  • 前端面试之闭包
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 用 Swift 编写面向协议的视图
  • const的用法,特别是用在函数前面与后面的区别
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​批处理文件中的errorlevel用法
  • #前后端分离# 头条发布系统
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (C#)获取字符编码的类
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (五)MySQL的备份及恢复
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)VC++中ondraw在什么时候调用的
  • (转载)虚函数剖析
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .Net Core与存储过程(一)
  • .NET Reactor简单使用教程