zoukankan      html  css  js  c++  java
  • scrapy的一个简单小项目

    使用scrapy抓取目标url下所有的课程名和价格,并将数据保存为json格式url=http://www.tanzhouedu.com/mall/course/initAllCourse

    观察网页并分析该网页:

    是一个ajax加载的页面,每次数据变化,但是url不变化,
    通过查看headers中的信息,得到每次点击下一页时真正请求的链接url
    观察发现每次翻页,请求变化的是offset的数值和时间戳

    1.创建项目

    使用命令:scrapy startproject 'project_name'得到对象的项目文件夹,里面包含scrapy的一些必要组件

    如下:

    具体文件含义,参见链接:http://www.cnblogs.com/pythoner6833/p/9012292.html

    2.明确抓取目标。

    编辑items.py文件,定义好需要抓取的数据字段名

    代码如下:

    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    #
    # See documentation in:
    # https://doc.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    
    class TanzhouItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        """
        定义爬取的目标,本案例中只爬取标题和价格两个内容
        所以定义两个字段
        """
        # 课程金额
        money = scrapy.Field()
        # 课程名称
        title = scrapy.Field()

    3.编辑爬虫。

    进入spiders文件夹下,创建爬虫文件,命令:scrapy  genspider  'spider_name'  "start_url"

    就会得到一个以spider_name命名的文件,在里面编写爬虫的逻辑

    # -*- coding: utf-8 -*-
    """
    抓取:http://www.tanzhouedu.com/mall/course/initAllCourse
    下的所有课程名称和价格,并保存为json格式
    
    网页分析:
    是一个ajax加载的页面,每次数据变化,但是url不变化,
    通过查看headers中的信息,得到每次点击下一页时真正请求的链接url
    观察发现每次翻页,请求变化的是offset的数值和时间戳
    
    
    1.首先创建一个爬虫项目。
        使用命令:scrapy startproject 'pro_name'  # pro_name是项目名称
        输入命令后,会自动出现一个用pro_name的项目文件夹,
        里面包含一个scrapy项目所必要的文件
    
    2.明确爬取目标,编辑items.py文件,定义需要爬取的字段。
    
    3.编辑爬虫。进入spiders文件夹下,创建爬虫文件。
        使用命令:scrapy genspider 'spider_name' 'start_url'
        生成一个爬虫,名字为spider_name,初始爬取url为start_url
        会在spiders文件夹下生成一个spider_name.py的文件,
        里面包含一个name=‘spider_name’, name是不同爬虫的唯一标识,不能重复
        start_url是爬虫的第一个爬取链接(可修改),并返回一个response
        解析response中的其他可用链接和数据
    
    4.将爬取到的数据通过yield,丢给pipelines.py文件保存,
    在pipelines.py文件中编写保存文件的逻辑
    
    5.运行爬虫,使用命令:scrapy crawl "spider_name"
    
    注:在配置文件中打开头信息和管道
    """
    
    import scrapy
    
    # 从items文件中导入已经写好的待爬取目标(money和title)
    from tanzhou.items import TanzhouItem
    import time
    
    class TzSpider(scrapy.Spider):
        name = 'tz'  # 爬虫名称。区别于其他爬虫的唯一ID。
        allowed_domains = ['tanzhouedu.com']  # 允许域名
    
        # 爬虫的第一个爬取链接,启动爬虫就执行,并返回一个response交给parse函数
        start_urls = ['http://www.tanzhouedu.com/mall/course/initAllCourse']
        offset = 0
    
        def parse(self, response):
            item = TanzhouItem()  # 实例化。实例一个爬取字段的实例对象。
    
            # 通过xpath解析response,并从中提取数据,得到xpath对象
            node_list = response.xpath('//div[@id="newCourse"]/div/div/ul/li')
            for node in node_list:
                # extract_first() 是取对象的值,得到一个字符串
                item['money'] = node.xpath('./div/span/text()').extract_first()
                item['title'] = node.xpath('./a/@title').extract_first()
    
                yield item
                # yield将item返回,scrapy_engine通过管道,将item交给pipelines
                # pipelines.py文件用于爬取结果的保存
    
            if node_list == []:
                """
                下一页到最后时,xpath匹配到的是一个空列表
                此时已没有可爬取页面,return结束程序。
                """
                return
    
            self.offset += 20  # 构造变化的offset,每次翻页增加20
    
            # yield将新的请求丢给调度器,然后交给下载器,继续下载页面,得到response
            # callback回调parse函数,实现循环抓取
            yield scrapy.Request(url="http://www.tanzhouedu.com/mall/course/initAllCourse?params.offset="
                + str(self.offset) +"&params.num=20&keyword=&_=" + str(int(time.time() * 1000)), callback=self.parse)

    4.编写保存数据的逻辑。

    在pipelines.py文件中编写保存数据的逻辑

    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    #
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    
    import json
    
    class TanzhouPipeline(object):
        """
        编写爬取到的数据保存的逻辑
        """
        def __init__(self):
            """
            可选择实现,对参数做一些初始化的处理
            """
            pass
    
        def open_spider(self, spider):
            """
            重写open_spider函数,该函数在爬虫启动时就自动执行
            :param spider:
            :return:
            """
            self.file = open("tz.json", 'w', encoding='utf-8')
    
        def process_item(self, item, spider):
            """
            将yield丢过来的数据进行一定的处理并保存
            :param item:
            :param spider:
            :return:
            """
            # 管道传过来的数据item是一个对象,将它转化为字典,然后存储
            content = json.dumps(dict(item), ensure_ascii=False) + '
    '
            self.file.write(content)
            return item
    
        def close_spider(self, spider):
            """
            重写该函数,爬虫执行完毕后执行该函数
            :param spider:
            :return:
            """
            self.file.close()

    5.运行爬虫。

    使用命令:scrapy crawl  "spider_name"

     运行结果:

    得到一个保存有抓取结果的json文件

     完整代码

    参见:https://github.com/zInPython/tanzhou

  • 相关阅读:
    Junit单元测试
    点餐系统
    文件的横纵转换
    零碎知识--日积月累
    json校验
    程序员必须收藏的14个顶级开发社区!
    管理员权限
    Thinking In Java 读书笔记
    学生考试系统
    JeeSite开发笔记
  • 原文地址:https://www.cnblogs.com/pythoner6833/p/9012695.html
Copyright © 2011-2022 走看看