Scrapy项目搭建的完整步骤

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

(一)scrapy整体架构图

在这里插入图片描述

(二)Scrapy主要组件

  • 1、引擎(Scrapy): 用来处理整个系统的数据流处理, 触发事务(框架核心)。
  • 2、调度器(Scheduler): 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址。
  • 3、下载器(Downloader): 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)。
  • 4、爬虫(Spiders): 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。
  • 5、项目管道(Pipeline): 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
  • 6、下载器中间件(Downloader Middlewares): 位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
  • 7、爬虫中间件(Spider Middlewares): 介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
  • 8、调度中间件(Scheduler Middewares): 介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
scrapy startproject yaowang    #创建项目

在这里插入图片描述
下面来简单介绍一下各个主要文件的作用:

scrapy.cfg:项目的配置文件
yaowang/:项目的Python模块,将会从这里引用代码
yaowang/items.py:项目的字段定义文件
yaowang/pipelines.py:项目的管道文件
yaowang/settings.py:项目的设置文件
yaowang/spiders/:存储爬虫代码目录

(三)定义存储对象(yaowangl/items.py)
Items是装载我们抓取数据的容器。它们工作像简单的Python字典,它提供更多的保护,比如对未定义的字段提供填充功能防止出错.
Itmes.py
在这里插入图片描述

(四)制作爬虫 (yaowang/spiders/)

1、在当前目录下输入命令,将在yaowang/spider目录下创建一个名为的爬虫,并指定爬取域的范围:

scrapy genspider yao 111.com.cn   #创建爬虫

2、打开 tutorial/spider目录里的 hsw.py,默认增加了下列代码:
yao.py

# -*- coding: utf-8 -*-
import scrapy
from lxml import etree
from yaowang.items import YaowangItem

class YaoSpider(scrapy.Spider):
    name = 'yao'
    allowed_domains = ['111.com.cn']
    start_urls = []

    for i in range(1,51):
        url = f'https://www.111.com.cn/categories/953710-j{i}.html'
        start_urls.append(url)

    def parse(self, response):
        # with open('yaowang.html','w',encoding='utf-8')as fp:
        #     fp.write(response.body.decode('gbk'))
        # 提取HTML页面
        tree = etree.HTML(response.body.decode('gbk'))
        # 所有药品的盒子
        li_list = tree.xpath('//ul[@id="itemSearchList"]/li')
        # print(len(li_list))
        for li in li_list:
            # 实例化item
            item = YaowangItem()

            # 药名
            name = li.xpath('./div[1]/p[@class="titleBox"]/a/text()')
            name = [i.strip() for i in name]
            name = ''.join(name).strip()
            # print(name)

            # 图片链接
            href = li.xpath('./div[1]/a//img/@src')[0]
            # print(href)

            # 价格
            price = li.xpath('./div[1]/p[@class="price"]//span/text()')[0]
            price = price.strip()
            # print(price)

            # 药店
            store = li.xpath('./div[1]/div[@class="sell_type_div"]/span[2]//text()')[0]
            # print(store)

            # 详情url
            url = li.xpath('./div[1]/a/@href')[0]
            full_url = "https:" + url
            # print(full_url)

            item['name'] = name
            item['href'] = href
            item['price'] = price
            item['store'] = store
            item['url'] = full_url
            # 默认过滤相同的url请求
            yield scrapy.Request(url=full_url,callback=self.parse_detail,meta={'data':item})
            # yield item

    # 二级页面,详情页数据提取
    def parse_detail(self,response):
        # 继承上一页页面的item数据
        item = response.meta['data']
        # with open('yaowang_detail.html','w',encoding='utf-8')as fp:
        #     fp.write(response.body.decode('gbk'))
        tree = etree.HTML(response.body.decode('gbk'))
        # 商品详情信息
        # div = tree.xpath('//div[@class="goods_intro"]/table')
        # 商品名称
        shop_name = tree.xpath('//div[@class="goods_intro"]//tr[1]/td/text()')[0]
        print("========",shop_name)
        # 品牌
        brand = tree.xpath('//div[@class="goods_intro"]//tr[2]/td[1]/text()')[0]
        # print("========", brand)
        # 规格
        standard = tree.xpath('//div[@class="goods_intro"]//tr[2]/td[2]/text()')[0]
        # print("========", standard)
        # 重量
        weight = tree.xpath('//div[@class="goods_intro"]//tr[3]/td[1]/text()')[0]
        # print("========", weight)
        # 生产厂商
        produce = tree.xpath('//div[@class="goods_intro"]//tr[3]/td[2]/text()')[0]
        # print("========", produce)
        # 批准文号
        approval_num = tree.xpath('//div[@class="goods_intro"]//tr[4]/td[1]//text()')
        approval_num = [i.strip() for i in approval_num]
        approval_num = ''.join(approval_num)
        # print("========", approval_num)
        # 产品类型
        produce_type = tree.xpath('//div[@class="goods_intro"]//tr[4]/td[2]/text()')[0]
        produce_type = produce_type.strip()
        # print("========", produce_type)

        # item存储数据
        item['shop_name'] = shop_name
        item['brand'] = brand
        item['standard'] = standard
        item['weight'] = weight
        item['produce'] = produce
        item['approval_num'] = approval_num
        item['produce_type'] = produce_type

        yield item

3、要建立一个Spider, 你必须用scrapy.Spider类创建一个子类,并确定了三个强制的属性 和 一个方法。

  • ① name ="":这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
  • ②allow_domains=[]是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。
  • ③ start_urls=():爬取的URL元祖/列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些起始URL中继承性生成。
  • ④ parse(self,response):解析的方法,每个初始URL完成下载后将被调用,调用的时候传入从每一个URL传回的Response对象来作为唯一参数,主要作用如下:
    负责解析返回的网页数据(response.body),提取结构化数据(生成item) b) 生成需要下一页的URL请求。

4、修改parse方法,添加parse_item方法
现在我们修改yao.py文件将start_urls的值修改为需要爬取的初始url

start_urls = []
for i in range(1,51):
    url = f'https://www.111.com.cn/categories/953710-j{i}.html'
    start_urls.append(url)

这里不使用response自带的xpath,使用lxml xpath
from lxml import etree

在这里插入图片描述

5、然后运行一下看看,在yaowang目录下执行:

scrapy crawl yao -o yao.csv
scrapy保存信息的最简单的方法主要有四种,-o 输出指定格式的文件,命令如下:
json格式,默认为Unicode编码
scrapy crawl yao -o yao.json
json lines格式,默认为Unicode编码
scrapy crawl yao -o yao.jsonl
csv 逗号表达式,可用Excel打开
scrapy crawl yao -o yao.csv
xml格式
scrapy crawl yao -o yao.xml


输出日志到指定文件,但是日志就不会输出到屏幕上了
scrapy crawl yao -s LOG_FILE=yao.log

6、利用pipelines.py:项目的管道文件进行数据的保存
mysql保存::

class YaowangPipeline(object):
    def __init__(self):
        # 建立数据库连接
        self.con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='q1q1q1',
            database='aabbcc',
            charset='utf8')
        # 创建操作游标
        self.cursor = self.con.cursor()

    def process_item(self, item, spider):
        print("="*30)
        # data_list.append(dict(item))
        # with open('yaowang.json','w',encoding='utf-8')as fp:
        #     json.dump(data_list,fp,ensure_ascii=False)

        name = item['name']
        href = item['href']
        price = item['price']
        store = item['store']
        url = item['url']
        shop_name = item['shop_name']
        brand = item['brand']
        standard = item['standard']
        weight = item['weight']
        produce = item['produce']
        approval_num = item['approval_num']
        produce_type = item['produce_type']
        # 定义sql语句
        # sql = "INSERT INTO yaowang_er(name,href,price,store,url,shop_name,brand,standard,weight,produce,approval_num,produce_type) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
        #
        # # 执行sql语句
        # self.cursor.execute(sql,(name,href,price,store,url,shop_name,brand,standard,weight,produce,approval_num,produce_type))
        # # 保存修改
        # self.con.commit()

        return item
    def __del__(self):
	     # 关闭操作游标
	     self.cursor.close()
	     # 关闭数据库连接
	     self.con.close()  

MongoDB保存:

class YaowangMongoPipeline(object):
    def __init__(self):
        # 创建客户端
        self.client = pymongo.MongoClient('localhost')
        # 创建数据库
        self.db = self.client['yaowang']
        # 创建集合
        self.collection = self.db['yao_info']
    def process_item(self, item, spider):
        print("="*30)
        self.collection.insert(dict(item))
        return item

然后settings.py 中使用管道文件配置,进行数据保存

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   # 'taoche.pipelines.TaochePipeline': 300,
   'taoche.pipelines.TaocheMongoPipeline': 300,
}

运行爬虫:

scrapy crawl yao

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孜孜孜孜不倦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值