python爬虫之scrapy 框架学习复习整理一

说明:

由于好久(半年以上了)没有用到scrapy框架做爬虫了,日常的使用request+多线程和协程就能高速爬取了,时间久了发现不怎么熟练了,抽空闲时间再复习一下,巩固。

我的工作环境:

windows10系统
python3.6

学习目标

  1. 创建一个Scrapy项目
  2. 定义提取的结构化数据(Item)
  3. 编写爬取网站的 Spider 并提取出结构化数据(Item)
  4. 编写 Item Pipelines 来存储提取到的Item(即结构化数据)

1、scrapy的爬虫流程:

在这里插入图片描述
在这里插入图片描述

2、scrapy入门:

  1. 创建一个scrapy项目
    scrapy startproject mySpider

  2. 生成一个爬虫
    scrapy genspider xiaohuar “xiaohuar.com”

  3. 提取数据
    完善spider,使用xpath等方法

  4. 保存数据
    pipeline中保存数据

3、几个必须掌握的全局命令:

1. scrapy startproject(创建项目)
2. scrapy genspider demo demo.com (初始化爬虫文件)
3. scrapy crawl XX(运行XX蜘蛛)、
4. scrapy shell http://www.scrapyd.cn(调试网址为http://www.scrapyd.cn的网站)-- 可以用来调试测试response含有的方法,或者xpath提取的方法,进行测试。

1、创建一个scrapy项目

scrapy startproject mySpider

scrapy startproject这里是固定的,注意scrapy和startproject和mySpider中间是有空格的!后面的:mySpider是我们创建的蜘蛛名字,后面我们运行的时候用得到,你需要根据你的情况创建,比如你是想爬取淘宝你可以这样创建:

scrapy startproject taobao

会在当前目录下生成一个test_1的目录,结构如下图
在这里插入图片描述

下面来简单介绍一下各个主要文件的作用:

  1. scrapy.cfg :项目的配置文件
  2. mySpider/ :项目的Python模块,将会从这里引用代码
  3. mySpider/items.py :项目的目标文件
  4. mySpider/pipelines.py :项目的管道文件
  5. mySpider/settings.py :项目的设置文件
  6. mySpider/spiders/ :存储爬虫代码目录

2、明确目标(mySpider/items.py)

我们打算抓取:http://top.baidu.com/百度风云榜实时热点前十条信息

  1. 打开mySpider目录下的items.py
  2. Item 定义结构化数据字段,用来保存爬取到的数据,有点像Python中的dict,但是提供了一些额外的保护减少错误。
  3. 可以通过创建一个 scrapy.Item 类, 并且定义类型为 scrapy.Field的类属性来定义一个Item(可以理解成类似于ORM的映射关系)。
  4. 接下来,创建一个BaiduItem 类,和构建item模型(model)。

items.py 默认会是这种:

在这里插入图片描述

改为这个:

import scrapy

class BaiduItem(scrapy.Item):
    bd_id = scrapy.Field()
    bd_title = scrapy.Field()
    bd_num = scrapy.Field()

在这里插入图片描述

3、制作爬虫 (spiders/baidu.py)

这里主要分为俩步:爬数据+取数据
在这里插入图片描述

1、制作爬虫文件默认格式

cd mySpider
scrapy genspider baidu "top.baidu.com/"

然后会在spiders下面生成一个baidu.py文件,里面内容是下面的默认格式,自己再进行修改。
在这里插入图片描述

打开 mySpider/spider目录里的 baidu.py,默认增加了下列代码:
在这里插入图片描述

其实也可以由我们自行创建baidu.py并编写上面的代码,只不过使用命令可以免去编写固定代码的麻烦

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

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

如果需要将start_urls的值修改为需要爬取的第一个url,或多个url,会多线程爬取这些。

2、修改parse()方法

  def parse(self, response):
	        # pass
	        print("进来了")
	        with open('./baidu.html', 'wb') as file:
	            file.write(response.body)

结果发现打印不出来“进来了”,我这里猜想是robot协议问题
在这里插入图片描述
更改robot协议,为False,并且将log级别更改为:

ROBOTSTXT_OBEY = False

_LEVEL = 'DEBUG'
LOG_LEVEL = "WARNING"

成功打印出“进来了”:
在这里插入图片描述

然后在项目目录下生成一个baidu.html,这个就是爬取http://top.baidu.com/返回的页面。
在这里插入图片描述
这个时候,我们可以提取数据了,但是我忘记之前是如何提取的了,我只记得和request返回的是不一样的,怎么办,这时候可以考虑打印出来,看看response是什么类型,有什么方法:
在这里插入图片描述
打印出类型和拥有的方法:
在这里插入图片描述

3、使用xpath提取数据:

保存的页面分析:
在这里插入图片描述

提取代码:

 def parse(self, response):
        # 测试是否能进来
        print("进来了")
        # 保存下来响应页面
        # with open('./baidu.html', 'wb') as file:
        #     file.write(response.body)
        # 打印出类型和方法
        # print("type_response", type(response))
        # print("dir_response", dir(response))
        # xpath提取数据
        li_list = response.xpath('//*[@id="hot-list"]//li')
        items = []
        for li in li_list:
            # 将我们得到的数据封装到一个 `BaiduItem` 对象
            item = BaiduItem()
            # extract()方法返回的都是字符串
            # 名次
            bd_id = li.xpath('./span[@class="num-top" or @class="num-normal"]/text()').extract()
            # 标题
            bd_title = li.xpath('./a[@class="list-title"]/text()').extract()
            # 搜索指数
            bd_num = li.xpath('./span[@class="icon-rise" or @class="icon-fall" or @class="icon-fair"]/text()').extract()

            # xpath返回的是包含一个元素的列表
            item['bd_id'] = bd_id[0]
            item['bd_title'] = bd_title[0]
            item['bd_num'] = bd_num[0]
            print(bd_id, bd_title, bd_num)
            items.append(item)
            # 直接返回最后数据
        print("items",items)
        return items

注意点:

  1. 使用xpath提取字符串:
    后来补充测试,截图如图:
    在这里插入图片描述

    ①、extract() 返回的是一个包含字符串数据的列表【和getall()方法返回的结果一样】

    ②、extract_first() 返回的是列表的第一个字符串【和get()方法返回的结果一样,】

  2. response.xpath() 返回的是一个含有selector对象的列表

  3. 需要爬取的url必须在allowed_domains域名下的链接,allowed_domains里面可以存放多个域名,如果需要爬取其他地址,可以自己想需要爬取的跳转网页的域名加入allowed_domains的列表中。

打印出来的数据:
在这里插入图片描述

4、管道保存数据(pipelines.py)

先在pipelines.py文件中增加一句,测试内容:
在这里插入图片描述

发现没有进入管道pipelines在这里插入图片描述

我们修改baidu.py,将return改为yield,不能对于单个dict数据返回给管道pipelines
在这里插入图片描述
需要在setting里面把设置的管道注销的打开,这样才能进入管道。
在这里插入图片描述
这时候就可以进入管道了。
在这里插入图片描述

注意点:yield返回的只能是dict或者None,

yield返回进入管道的,只能是字典格式的,如果是其他的就会报错:
在这里插入图片描述

在这里插入图片描述

5、保存到MongoDB数据库:

管道代码:

from pymongo import MongoClient


class MyspiderPipeline(object):

    def open_spider(self, spider):
        print("准备创建一个数据库")
        # 这个会在项目开始时第一次进入pipelines.py进入,之后不再进入
        # 建立于MongoClient 的连接:
        self.client = MongoClient('localhost', 27017)
        # 得到数据库
        self.db = self.client['111_test_database_baidu']
        # 得到一个集合
        self.collection = self.db['111_test_collection_baidu']

    def close_spider(self, spider):
        print('项目结束,断开数据库连接')
        # 这个会在结束时开始时第一次进入pipelines.py进入,之后不再进入
        self.client.close()

    def process_item(self, item, spider):
        print("process_item", item, spider)
        print("type",type(item))
        # 储存到数据库
        print("准备保存到数据库")
        self.collection.save(dict(item))
        return item

注意点:

item看着是dict,但是还不python里面的dict,需要使用dict(item)转换一下,才能正常保存,不然报错,我这里改了就成功了:

成功报错效果图:
在这里插入图片描述

参考:
https://doc.scrapy.org/en/latest/topics/item-pipeline.html

版权声明:本文为weixin_42081389原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42081389/article/details/102390279

智能推荐

python爬虫之scrapy 框架学习复习整理四--验证发送请求时携带cookies的4种有效性方法

文章目录 说明: 一、使用requests模块初步验证cookies的有效性: 1、先分析页面结构: ①、登录状态 ②、未登录状态 ③、对比结论: 2、接下来我们使用requests模块测试cookies的有效性: ①、测试代码: ②、未登录状态 ③、登录状态 ④、结论 二、使用scrapy测试携带cookie的方法 1、命令生成项目和初始化爬虫: 2、修改setting 3、初步更改爬虫程序 4...

自学Python之Scrapy爬虫:(一)爬虫基础

转载的老板请注明出处:http://blog.csdn.net/cc_xz/article/details/78710314万分感谢! 在本篇中,你将了解到: 1.爬虫概念的基本论述。 2.Python的虚拟环境。 3.如何创建一个Scrapy项目。 4.Scrapy框架结构及执行流程。 爬虫概念的基本论述: 什么是爬虫? 当你看到这篇文章时,是使用浏览器打开了CSDN这个网站中的某个页面。也就是...

python学习笔记之爬虫框架scrapy(十七)

一、安装 执行以下命令安装scrapy 注意: Scrapy是用纯Python编写的,并且依赖于一些关键的Python包(以及其他一些包): lxml,高效的XML和HTML解析器 parsel,是在lxml之上编写的HTML / XML数据提取库 w3lib,一个用于处理URL和网页编码的多功能助手 扭曲的异步网络框架 加密和pyOpenSSL,以处理各种网络级安全需求 二、Scrapy教程 本...

Python+Selenium+Autolt选择本地文件上传至网站

如果网站有上传文件的功能,selenium不提供对本地元素的定位,如何使用python选择本地文件进行上传呢 可以使用Autolt工具上传文件: 1、下载网址:https://www.autoitscript.com/site/autoit/downloads/ 2、点击“Downlad ZIP”下载 3、解压缩下载的ZIP文件 4、打开脚本编辑器文件夹,有一个SciTE....

数据结构系列之一-线性表

数据结构系列--线性表 慧子和她的3D 慧子和她的3D      暑期工作搞不下去,不如趁着现在整块时间搞编程。学习资料书《大话数据结构》,前面两章的铺垫感性知识,看看过,从第三章开始正餐。 01 — 线性表 线性表:零个或多个数据元素的有限序列。用数学语言表达:       ...

猜你喜欢

Linux系统的远程操作练习

目录 一、将虚拟机Ubuntu系统的网络连接设置为“桥接模式”,并配置Ubuntu的IP、网关参数 二、在win10系统下用putty登录ubuntu系统 三、VNC server VNC viewer 思考 一、将虚拟机Ubuntu系统的网络连接设置为“桥接模式”,并配置Ubuntu的IP、网关参数 1.打开虚拟机,进入设置 点击网络适配器,选择桥...

ORACLE----TimeStamp(时间戳)自动更新

之前对id的自增长进行了设置,原以为时间戳的更新也类似,使用序列之类的,但最终发现跟序列没半毛钱关系。触发器是肯定要用的,但编写脚本也是需要的。 (1)创建触发器 图2中,我们要选择事件(即例子中的INSERT,UPDATE),触发时间(即INSERT,UPDATE事件的前或后,例子中是before),列(例子中为MODIFIED_DATE,为TimeStamp类型),新旧值(为系统默认值OLD和...

数字图像处理:对数变换

设置窗口大小的函数: namedWindow("窗口名", 0); resizeWindow("窗口名", width, height);...

LeetCode(剑指offer-tree)-面试题26. 树的子结构

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值。 例如: 树的遍历方式为:前序遍历 给定的树 A: 给定的树 B: 返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。 示例 1: 示例 2: 限制: 题源链接:https://leetcode-cn.com/problems/shu-de-z...

大数据笔记14:Zebra项目分析与实施

第14天——Zebra项目分析与实施 第一部分 Zebra项目概述 一、Zebra项目介绍 二、日志数据结构分析 三、数据以| 分割后,每个数据项的含义 四、Zebra项目整体架构 (一)技术架构 (二)工程架构 五、Zebra业务说明 六、Zebra项目设计思想 第二部分 Zebra项目实施过程 一、创建Maven项目ZebraProject 二、zebra_jobtra...