Python爬虫之scrapy框架初识

Python爬虫之scrapy框架

  • scrapy框架
  • 安装scrapy
  • 使用scrapy框架爬取校花网数据,并持久化存储

1. scrapy框架

  scrapy框架是一个为了爬取网站数据,提取结构性数据而编写的应用框架,集成了多种功能(高性能异步下载,队列,分布式,数据解析,持久化存储)的具有很强通用性的项目模板.

2. 安装scrapy

2.1 Linux环境

pip3 install scrapy

2.2 Windows环境

# 1.
pip3 install wheel

# 2. 下载twisted
http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

# 3. 进入下载目录,执行安装命令
pip3 install Twisted-19.2.1-cp36-cp36m-win_amd64.whl

# 4. 
pip3 install pywin32

# 5. 
pip3 install scrapy

3. 使用scrapy框架

# 项目目录结构

scrapy.cfg     项目的主要配置信息
items.py       设置数据存储模板,用于结构化数据
pipelines      数据持久化存储
setting.py     配置文件(递归的层数,并发数,延迟下载等)
spiders        爬虫目录

3.1 创建项目

scrapy startproject xiaohuapro

3.2 创建爬虫应用程序

# 进入项目目录
cd xiaohuapro

# 创建一个应用程序 xiaohua
scrapy genspider xiaohua www.xxx.com

3.3 此时会在spiders目录下生成一个xiaohua.py文件

xiaohua.py文件的作用:

  1. 配置要爬取的域名url列表
  2. scrapy请求url后会执行回调函数parse,参数response是访问url后获取的响应对象
  3. response.text 获取字符串类型的响应内容
  4. response.body 获取字节类型的响应内容
  5. 封装了etree模块,可以使用xpath进行解析
  6. 解析后的数据被封装在Selector对象中,需要使用extract()或extract_first()获取数据
  7. 使用yield把数据提交到管道,由管道进行持久化存储
# -*- coding: utf-8 -*-
import scrapy
from xiaohuapro.items import XiaohuaproItem

class XiaohuaSpider(scrapy.Spider):
    name = 'xiaohua'
    #允许爬取的域名(如果遇到非该域名的url则爬取不到数据)
    # allowed_domains = ['www.xxx.com']
    start_urls = ['http://www.521609.com/meinvxiaohua/']

    #访问起始URL并获取结果后的回调函数,该函数的response参数就是向起始的url发送请求后,获取的响应对象.该函数返回值必须为可迭代对象或者NUll 
    def parse(self, response):
        li_list = response.xpath('//div[@class="index_img list_center"]/ul/li')

        for li in li_list:
            title = li.xpath('./a[2]/text() | ./a[2]/b/text()').extract_first()
            pic_url = "http://www.521609.com" + li.xpath('./a[1]/img/@src').extract_first()
            item = XiaohuaproItem()
            item["title"] = title
            item["pic_url"] = pic_url
            # 使用yield 把数据提交到管道
            yield item

3.4 修改setting.py配置文件(创建好爬虫应用之后第一个要做的事)

# UA伪装
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.'

# 是否遵循rebits.txt协议
ROBOTSTXT_OBEY = False

# 日志级别(开发时可以设置为INFO,或者ERROR)
LOG_LEVEL = "INFO"

# 配置管道,持久化存储的方式(文件存储,数据库存储,redis存储等)
ITEM_PIPELINES = {
    # 'xiaohuapro.pipelines.XiaohuaproPipeline': 300,
    # 'xiaohuapro.pipelines.MysqlPipeline': 300,
    'xiaohuapro.pipelines.RedisPipeline': 300,
}

...

3.5 配置items.py文件

import scrapy

# 配置结构化数据的字段
# 在这里添加要爬取的数据的字段名
class XiaohuaproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    pic_url = scrapy.Field()

3.6 配置管道文件pipelines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import pymysql
import redis
import json


# ### 持久化存储到文件
class XiaohuaproPipeline(object):
    # 声明一个文件对象
    f = None

    # 打开spider管道程序
    def open_spider(self, spider):
        # 实例化一个文件对象
        self.f = open("./xiaohua.txt", "w", encoding="utf-8")

    # 持久化数据的过程
    def process_item(self, item, spider):
        title = item["title"]
        pic_url = item["pic_url"]
        # 写入数据到文件对象
        self.f.write(title + " : " + pic_url + "\n")
        return item

    # 关闭管道
    def close_spider(self, spider):
        # 关闭文件对象
        self.f.close()


# ### 持久化数据到MySQL数据库
class MysqlPipeline(object):
    # 声明一个连接对象和一个游标对象
    conn = None
    cursor = None

    # 打开管道程序
    def open_spider(self, spider):
        # 实例化一个mysql连接
        self.conn = pymysql.Connect(
            host="10.0.3.132",
            port=3306,
            user="root",
            password="admin",
            db="db1",
            charset="utf8"
        )

    # 持久化数据的过程
    def process_item(self, item, spider):
        title = item["title"]
        pic_url = item["pic_url"]
        # 定义一个sql
        sql = "insert into xiaohua values('{}','{}')".format(title, pic_url)
        # 使用mysql的连接对象conn实例化一个游标对象
        self.cursor = self.conn.cursor()

        # 事务处理,sql执行有问题就回滚
        try:
            self.cursor.execute(sql)
        except Exception as e:
            self.conn.rollback()

        # 提交数据到数据库
        self.conn.commit()
        return item

    # 关闭管道程序
    def close_spider(self, spider):
        # 关闭游标对象和连接对象
        self.cursor.close()
        self.conn.close()


# ### 持久化数据到redis数据库
class RedisPipeline(object):
    # 声明一个redis连接对象
    conn = None
    
    # 打开管道程序
    def open_spider(self, spider):
        # 实例化一个redis连接对象
        self.conn = redis.Redis(host="10.0.3.132", port=6379)

    # 持久化数据的过程
    def process_item(self, item, spider):
        title = item["title"]
        pic_url = item["pic_url"]

        # 把解析数据放到一个字典中
        dic = {
            "title": title,
            "pic_url": pic_url
        }
        # 使用连接对象把数据存储到redis数据库中(注意使用json序列化字典)
        self.conn.lpush("xiaohua", json.dumps(dic))

        return item

    # 关闭管道
    def close_spider(self, spider):
        # 关闭redis连接
        self.conn.close()

pipelines.py
pipelines.py

3.7 终端执行命令开始爬虫程序

scrapy crawl xiaohua
posted @ 2020-01-09 22:04  心随我动丶  阅读(234)  评论(0)    收藏  举报