scrapy框架基础

一、简介

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。

二、下载安装

  • Linux:
    • pip install scrapy
  • widows:

三.简单使用

  1.创建scrapy工程:scrapy startproject projectName      (projectName    项目名)

  2.创建爬虫文件:scrapy genspider  spiderName www.xxx.com    (爬虫文件的名称, 起始的url)

  3.编写爬虫文件:在步骤2执行完毕后,会在项目的spiders中生成一个应用名的py爬虫文件,文件源码如下:

# -*- coding: utf-8 -*-
import scrapy


class FistSpider(scrapy.Spider):
    # 爬虫文件的名称
    name = 'fist'
    
    # 允许的域名(只有被允许的域名才能发送),一般不用,注掉都可以被发送
    # allowed_domains = ['www.xxx.com']
    
    # 起始url列表(只能放url)
    start_urls = ['https://baidu.com/']
    
    # 用来实现数据解析
    def parse(self, response):
        print("响应对象为:",response)

4.设置修改settings.py配置文件相关配置: 

# 修改内容及其结果如下:
19行:USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' #伪装请求载体身份

22行:ROBOTSTXT_OBEY = False  #可以忽略或者不遵守robots协议

5. 运行爬虫文件

    scrapy crawl 爬虫文件名

    scrapy crawl 爬虫文件名 --nolog # 不打印日志运行

 

持久化存储

存储爬取到的糗事百科热点的内容与发布作者

1、基于终端指令的持久化存储:只可以将parse返回值进行本地文件的存储

class TwoSpider(scrapy.Spider):
    name = 'qiubai'
    # allowed_domains = ['www.xxx.com']   # 允许的域名
    start_urls = ['https://www.qiushibaike.com/text/']  # 起始url列表(只能放url)

# 1.基于终端指令的持久化存储:只可以将parse返回值进行本地文件的存储.
    def parse(self, response):
        div_list = response.xpath('//div[@id="content-left"]/div')
        all_data_list = []
        for div in div_list:
            # author = div.xpath('./div[1]/a[2]/h2/text()')[0].extract()
            # 如果可以保证xpath返回的列表中只有一个元素,则可以直接使用下述方法
            author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
            content = div.xpath('./a/div/span//text()').extract()  # 将列表中所有的selector对象中的数据取出返回也是列表
            content = ''.join(content)
            dic = {
                'author': author,
                'content':content
            }
            all_data_list.append(dic)

        return all_data_list

 

  scrapy crawl qiubai -o qiubai.csv   # 运行qiubai爬虫文件并将返回内容存到qiubai.csv中

2.基于管道的持久化存储(通用性较强)

  • 1.进行数据解析
  • 2.在item类中定义相关的属性(为了存储解析到的数据)
  • 3.在parse方法中实例化一个item类型的对象
  • 4.将解析到的数据存储到item类型的对象中
  • 5.使用yiled item 将item对象提交给管道 (process_item方法,提交一次调用一次)
  • 6.在管道文件的process_item方法中接收item且对item中存储数据进行持久化存储
  • 7.在settings配置文件中开启管道
    def parse(self, response):
        div_list = response.xpath('//div[@id="content-left"]/div')
        all_data_list = []
        for div in div_list:
            # author = div.xpath('./div[1]/a[2]/h2/text()')[0].extract()
            # 如果可以保证xpath返回的列表中只有一个元素,则可以直接使用下述方法
            author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
            content = div.xpath('./a/div/span//text()').extract()  # 将列表中所有的selector对象中的数据取出返回也是列表
            content = ''.join(content)
            # 实例化一个item类型的对象:用来存储解析到的数据
            item = FirstbloodItem()
            item["author"] = author
            item["content"] = content

            # 向管道提交item类型的对象
            yield item

在item类中定义相关的属性  items.py

import scrapy


class FirstbloodItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 定义属性
    author = scrapy.Field()
    content = scrapy.Field()

在管道文件的process_item方法中接收item且对item中存储数据进行持久化存储  pipeline.py :

可以存到磁盘,数据库中

import pymysql
from redis import Redis

class FirstbloodPipeline(object):
    fp = None

    # 该方法只会被执行一次,
    def open_spider(self, spider):
        self.fp = open('./qiubai.txt', 'w', encoding='utf-8')

    # 用于处理item的方法,爬虫文件每次提交一次item方法就会被调用一次
    def process_item(self, item, spider):
        # 取出item中的值
        author = item["author"]
        content = item["content"]
        self.fp.write(author + ":" + content + "\n")
        return item  #返回给了下一个即将被执行的管道类

    # 关闭文件夹
    def close_spider(self,spider):
        self.fp.close()


class MysqlPileLine(object):
    # 连接
    conn = None
    cusor = None
    def open_spider(self, spider):
        # 连接数据库
        self.conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password="", db='spider')
        print(self.conn)

    def process_item(self, item, spider):
        self.cusor = self.conn.cursor()
        try:
            self.cusor.execute('insert into qiubai values("%s","%s")'%(item['author'],item['content']))
            self.conn.commit()
        except Exception as e:
            print(e)
            self.conn.rollback()
        return item  # 返回给下一个即将被执行的管道类

    def close_spider(self,spider):
        self.cusor.close()
        self.conn.close()


class RedisPipeLine(object):
    conn = None
    def open_spider(self,spider):
        self.conn = Redis(host='127.0.0.1',port=6379)
    def process_item(self,item,spider):
        dic = {
            'author':item['author'],
            'content':item['content']
        }
        self.conn.lpush('qiubaiData',dic)

在settings配置文件中开启管道

# 开启管道,让管道类生效
ITEM_PIPELINES = {
   'firstBlood.pipelines.FirstbloodPipeline': 300,  # 数值表示优先级
   'firstBlood.pipelines.MySqlPipeline': 301,
   'firstBlood.pipelines.RedisbloodPipeline': 303,
}

使用scrapy爬取chouti的热点内容与发布者

(递归爬取解析多页页面数据)

import scrapy

from choutiPro.items import ChoutiproItem
class ChoutiSpider(scrapy.Spider):
    name = 'chouti'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://dig.chouti.com/r/scoff/hot/1']

    #定义一个通用的url模板
    url = 'https://dig.chouti.com/r/scoff/hot/%d'
    pageNum = 1

    def parse(self, response):
        div_list = response.xpath('//div[@id="content-list"]/div')
        for div in div_list:
            content = div.xpath('./div[2]/div[1]/a/text()').extract_first()
            author = div.xpath('./div[2]/div[2]/a[4]/b/text()').extract_first()

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

            yield item

        #进行手动请求的发送
        if self.pageNum <= 120:
            self.pageNum += 1
            new_url = format(self.url%self.pageNum)
            yield scrapy.Request(url=new_url,callback=self.parse)

 

posted @ 2019-03-24 20:56  清风_Z  阅读(180)  评论(0编辑  收藏  举报