目录

一、Scrapy安装

1.mac系统

2.windows系统

二、使用scrapy爬取数据

1.新建一个scrapy工程

2.在spiders下新建一个爬虫文件

3.提取网页数据

三、保存数据到mongodb

四、再多学一点

1.添加请求头

2.Robot.txt设置

3.爬取多个页面

五、作业(这是一个考验)


前面我们都是从头开始编写爬虫,发送请求、解析网页、数据存储等每一个功能模块都需要自己实现。这一章我们学习的Scrapy是一个爬虫框架,它将上述的所有功能都封装到框架里。这样我们使用较少的代码就能完成爬虫的工作。

爬虫者往往会经历一个不用框架,到使用框架,再到不用框架的过程。初学者最开始只需要一个简单的小房子,所以使用Requests和bs4很方便。在学会使用Requests和bs4后,再使用Scrapy框架,你会发现一个新大路,原来只需要几行代码就可以完成爬虫,发现Scrapy很好用。但是渐渐地,你需要一些定制化地功能,Scrapy的条条框框并不能满足地功能,所以你可能还是会回到最开始的方法,但是此时你已经可以自己建一座华丽的大房子了。(《Python网络爬虫从入门到实践》第7章)

Scrapy 是一个快速的高级网页抓取框架,用于抓取网站并从其页面中提取结构化数据。它可用于广泛的用途,从数据挖掘到监控和自动化测试。

Scrapy主要的组件有引擎、调度器、下载器、爬虫、管道、爬虫中间件和下载器中间件。

如下图绿色箭头代表着数据流,各个模块的功能可简要概括如下:

  • 引擎:控制数据流在所有组件中的流动,开发者一般不需要修改
  • 调度器:从引擎接受请求并将他们加入爬虫队列,开发者一般不需要修改
  • 下载器:负责获取网页并提供给引擎,类似request获取网页,开发者一般不需要修改
  • 爬虫:负责解析网页,提取数据,类似解析网页,根据爬取的对象修改代码
  • 管道:负责存储数据,根据数据存储方式修改代码

一、Scrapy安装

1.mac系统

pip install Scrapy

2.windows系统

Scrapy也支持Python3了,在Windows下安装也很简单。但是强烈建议新创建一个scrapy_project的新工程,然后在这个工程的虚拟环境中安装scrapy,这是因为scrapy需要安装大量的第三方包文件。

pip install Scrapy

在venv环境下安装scrapy

巨多的第三方包

二、使用scrapy爬取数据

爬取某网的财经新闻数据,包含标题、链接、发布时间

1.新建一个scrapy工程

在pycharm的terminal中输入以下命令,这将为你创建一个新的Scrapy项目

scrapy startproject eastmoney_news_spider

最后一段字符串是你为这个Scrapy项目指定的名称,你可以根据自己的需要设定项目名称。

执行后,将会为你创建一个以项目名称命名的文件夹,该文件夹下的目录见下图。

  • scrapy.cfg: 项目的配置文件。
  • eastmoney_news_spider/: 该项目的python模块。之后您将在此加入代码。
  • eastmoney_news_spide/items.py: 项目中的item文件,用来定义爬虫提取的数据标签。
  • eastmoney_news_spide/middlewares.py: 项目中的中间件文件,用来设置请求头、cookies、代理ip池等。
  • eastmoney_news_spide/pipelines.py: 项目中的pipelines文件,用来对提取到的数据进行处理或者保存。
  • eastmoney_news_spide/settings.py: 项目的设置文件。
  • eastmoney_news_spide/spiders/: 放置spider代码的目录,一个项目可能会有多个爬虫,这里的爬虫代码指的是负责从网页中提取数据的部分。

2.在spiders下新建一个爬虫文件

在终端中使用cd将路径切换到spiders下

cd spiders

执行以下命令,创建一个spider文件

scrapy genspider news finance.eastmoney.com

news是爬虫的名称

finance.eastmoney.com是待爬取网站的域名

执行此段命令后,在Pycharm工程文件的目录中就可以看到多出来了一个news.py文件。打开后,我们可以看到以下初始内容

class NewsSpider(scrapy.Spider):name = 'news'allowed_domains = ['finance.eastmoney.com']start_urls = ['http://finance.eastmoney.com']def parse(self, response):

3.提取网页数据

  • 获取网页源代码

response.text

class NewsSpider(scrapy.Spider):name = 'news'allowed_domains = ['finance.eastmoney.com'] # 此地址为网站的域名start_urls = ['http://finance.eastmoney.com/a/ccjdd.html'] # 修改为待爬取的网页网址def parse(self, response):print(response.text)

在终端中输入命令运行爬虫

scrapy crawl news(第三个参数是spider文件中name的值)

  • 提取数据

使用lxml的xpath提取页面新闻的title、url、date数据。由于该网页新闻列表中有的楼层没有插入图片,导致不同楼层结构不一致,因此,设置了异常处理来解决这个问题。

使用scrapy中的xpath提取数据

在scrapy中可以直接使用xpath解析,但与lxml中使用XPath不同的是需要在XPath语句后面使用.extract()方法。

  • 实现数据流

一个Scrapy工程可以有多个爬虫,在items文件中可以针对不同的爬虫定义不同的抓取内容item。

这里定义一个NewsSpiderItem类,并继承的是scrapy.Item类。这个类就是在spider中将要采用fieldname = scrapy.Field()格式进行定义,fieldname是自定的字段名称。

在spider中将这个类实例化。

from eastmoney_news_spider.items import NewsSpiderItem  # 载入定义好的NewsSpiderItem

item = NewsSpiderItem() # 实例化这个类

接下了我们就可以向使用字典一样,使用item

item['title'] = 获取到的标题

item['url'] = 获取到的网址

item['date'] = 获取到的时间

完善后的代码:

import scrapy
from eastmoney_news_spider.items import NewsSpiderItemclass NewsSpider(scrapy.Spider):name = 'news'allowed_domains = ['finance.eastmoney.com/a/ccjdd.html']start_urls = ['http://finance.eastmoney.com/a/ccjdd.html']def parse(self, response):for content in response.xpath('//ul[@id = "newsListContent"]/li'):item = NewsSpiderItem()try:item['title'] = content.xpath('./div[2]/p[1]/a/text()').extract()[0].strip()item['url'] = content.xpath('./div[2]/p[1]/a/@href').extract()[0]item['date'] = content.xpath('./div[2]/p[3]/text()').extract()[0].strip()except:item['title'] = content.xpath('./div[1]/p[1]/a/text()').extract()[0].strip()item['url'] = content.xpath('./div[1]/p[1]/a/@href').extract()[0]item['date'] = content.xpath('./div[1]/p[3]/text()').extract()[0].strip()yield item

注意,最后通过 yield 来发起一个请求,并通过 callback 参数为这个请求添加回调函数,在请求完成之后会将响应作为参数传递给回调函数。

scrapy框架会根据 yield 返回的实例类型来执行不同的操作,如果是 scrapy.Request 对象,scrapy框架会去获得该对象指向的链接并在请求完成后调用该对象的回调函数。

如果是 scrapy.Item 对象,scrapy框架会将这个对象传递给 pipelines.py做进一步处理。这里我们yield item调用的就是scrapy.Item对象,接下来,我们在pipeline中将数据保存到mongodb中。

三、保存数据到mongodb

这里提供三种方案:

方案一:在pipeline设置数据库所有参数,单个数据逐个插入数据库

import pymongoclass NewsSpiderPipeline:def process_item(self, item, spider):host = 'localhost'port = 27017db_name = 'spider'client = pymongo.MongoClient(host=host,port=port)db = client[db_name]collection = db['eastmoney_news']collection.insert_one(dict(item))return item

方案二:在pipeline中引用settings,单个数据逐个插入数据库

  • 在settings中对mongodb的参数进行设置
MONGODB_HOST = 'localhost'
MONGODB_PORT = 27017
MONGODB_NAME = 'spider'
MONGODB_DOCNAME = 'eastmoney_news'

在pipeline中引用settings

class NewsSpiderPipeline:def process_item(self, item, spider):host = spider.settings['MONGODB_HOST']port = spider.settings['MONGODB_PORT']db_name = spider.settings['MONGODB_NAME']client = pymongo.MongoClient(host=host,port=port)db = client[db_name]collection = db[spider.settings['MONGODB_DOCNAME']]collection.insert_one(dict(item))return item

在pipeline中引用settings使用spider.settings,引用的方法和使用字典一样

在spider中引用settings使用self.settings,引用的方法和使用字典一样

方案三: 在pipeline中引用settings,在爬虫结束时,一次性批量插入数据库

我们知道mongodb应该少读少些,所以我们这里的策略是在spider开启时启动数据库;在每次回调时,将数据追加到一个列表中暂存起来;最后在spider关闭时,将数据一次性保存到数据库中,并关闭数据库。刚好pipleline中的组件完全支持这些需求。

class NewsSpiderPipeline:def open_spider(self, spider):host = spider.settings['MONGODB_HOST']port = spider.settings['MONGODB_PORT']db_name = spider.settings['MONGODB_NAME']self.client = pymongo.MongoClient(host=host, port=port)self.db = self.client[db_name]self.collection = self.db[spider.settings['MONGODB_DOCNAME']]self.item_list = []def process_item(self, item ,spider):self.item_list.append(dict(item))return itemdef close_spider(self,spider):self.collection.insert_many(self.item_list)print('{}条数据已存入数据库'.format(len(self.item_list)))self.client.close()print('数据库已关闭')
  • 在setting中开启pipeline

以上所有pipeline操作的实现都基于在settings中开启了pipeline 。要想开启pipeline 非常简单,只需要在settings的以下位置取消掉注释即可。

四、再多学一点

1.添加请求头

在settings文件中设置默认的请求头,此时发送请求时会默认携带此请求头。

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en','User-Agent': USER_AGENT
}

2.Robot.txt设置

默认为True,即默认遵守robot规则。根据实际需要可将此修改为False

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

3.爬取多个页面

在之前的例子中,我们只是爬取了一页的20篇新闻,如果要爬取后面的多个页面,我们该如何做呢?

  • 获取待爬取页面的链接

分析链接地址后发现页面所在的页数包含在链接地址中,即ccjdd_2代表第2页,ccjdd_3代表第3页。我们可以按此规律批量生成想要爬取的页面地址。

如下图红框中的第一行代码。

  • 循环爬取每一页

yield在第二部分的最后已经介绍过,yield scrapy.Request会生成一个scrapy.Request的实例,将url作为参数发送请求,并获得一个response,然后将response作为参数传递给回调函数parse,实际上这里调用的是parse本身,作用是对完成每一页的爬取。

五、作业(这是一个考验)

目标网站:站长之家 https://top.chinaz.com/

背景:站长之家是一家专门针对中文站点提供资讯、技术、资源、服务的网站,网站现有上百万用户。拥有最专业的行业资讯频道、国内最大的建站源码下载中心、站长聚集的站长社区、最大的建站素材库、最实用的站长工具,以及最大的中文网站流量统计分析系统。(摘自"百度词条")

需求:在站长之家的网站排行板块中,提供了行业排名、地区排名等多种分类网站排行数据。现在请你任选一种感兴趣的排名方式,摘取其中前10页的数据。

字段要求:一共7个字段,分别是网站名称web_name、网站域名domain、百度权重:baidu_weight、PR:PR、排名:rank、得分:score、网站简介:abstract。

技术要求:使用scrapy编写爬虫,最终将提取到的数据一次性储存到mongodb中;在mongodb中使用数据库查询命令查询PR值大于等于4分的所有数据并按从大到小排序。

需要提交的资料:整个scrapy项目文件、mongodb查询结果在text mode下的截图。

11.Scrapy框架基础-使用Scrapy抓取数据并保存到mongodb相关推荐

  1. 实现多线程爬取数据并保存到mongodb

    多线程爬取二手房网页并将数据保存到mongodb的代码: import pymongo import threading import timefrom lxml import etree impor ...

  2. php抓取数据并且保存到Excel

    <?php //获取网页内容 require './lib/PHPExcel-1.8/Classes/PHPExcel.php'; set_time_limit(0); //$arr = 'Ar ...

  3. 爬取链家网二手房数据并保存到mongodb中

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 爬取链家网二手房数据并保存到mongodb中 文章目录 前言 一.爬虫的介绍 二.协程的介绍 三.css选择器 四.基于asyncio ...

  4. git-history:一款用于分析保存在Git和SQLite中的网页抓取数据的工具

    大多数人都知道Git scraping,这是一种网页抓取工具编程技术,你可以定期将数据源快照抓取到Git存储库来跟踪数据源随时间的变化. 如何分析这些收集到的数据是个公认的难题.git-history ...

  5. Scrapy 模拟登陆知乎--抓取热点话题

    工具准备 在开始之前,请确保 scrpay 正确安装,手头有一款简洁而强大的浏览器, 若是你有使用 postman 那就更好了. Python 1 scrapy genspider zhihu 使用以 ...

  6. java启动scrapy爬虫,爬虫入门之Scrapy 框架基础功能(九)详解

    Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非 ...

  7. scrapy框架基础学习之囧事百科

    基础: 一.安装scrapy框架 pip install scrapy pip --default-timeout=2000 install -U scrapy 来下载scrapy让它的延迟检测时间变 ...

  8. Python爬虫之scrapy框架360全网图片爬取

    Python爬虫之scrapy框架360全网图片爬取 在这里先祝贺大家程序员节快乐,在此我也有一个好消息送给大家,本人已开通了微信公众号,我会把资源放在公众号上,还请大家小手动一动,关注过微信公众号, ...

  9. 第五章 Scrapy爬虫框架(5.1 Scrapy框架基础)

    Scrapy是一个高级Web爬虫框架,用于爬取网站并从页面中提取结构化数据.它可以用于数据挖掘.数据监控和自动化测试等多个方面.与之前讲过的Requests库和Selenium库不同,Scrapy更适 ...

最新文章

  1. 以太坊智能合约Demo
  2. iOS开发之--解决 swap file “*.swp”already exists!问题
  3. Python科学计算扩展库NumPy之np.array()与np.asarray()区别
  4. 趣味编程:从字符串中提取信息(参考答案 - 上)
  5. AI基础:Pandas简易入门
  6. Satwe楼板能用弹性模计算吗_现浇楼板淋水后却出现裂缝,还好老师傅有经验,多是这3点造成的...
  7. 微信公众号页面支付接口java,[Java教程]微信公众号支付(三):页面调用微信支付JS并完成支付...
  8. 【转】Dicom 学习笔记-Dicom 消息服务(DIMSE-C/DIMSE-N)
  9. Springboot 下 EasyExcel 的数据导入导出
  10. [10.2模拟] book
  11. threejs 绘制球体_Three.js 第一篇:绘制一个静态的3D球体
  12. linux系统交换空间,Linux中如何使用和管理交换空间
  13. mysql/mariadb 安装开启spinx引擎
  14. 2020 3月 月末总结(一个月的面试收获了什么)
  15. Golang——Go语言发展史(一)
  16. 基于springmvc的Junit与Jmockit使用
  17. 在wps中实现二级联动
  18. android ebusy,在Android中使用pjsip发送INVITE时出错:初始化媒体通道出错(PJ_EBUSY)...
  19. js计算字符串包含几个字符
  20. 杜子建:一个以弱势强的存在主义者

热门文章

  1. J2EE基础教程(1):简介和windows下环境配置
  2. JAVA计算机毕业设计上虞烟草物流配送系统(附源码、数据库)
  3. 机器学习教学 plt.scatter()绘制散点图
  4. java catch中抛出异常_简单了解Java编程中抛出异常的方法
  5. 关于【抛硬币】的思考
  6. Android menu属性详解
  7. C语言设计模式-封装-继承-多态
  8. 二分查找、快速排序对比和详解
  9. 栈的基本操作及其应用
  10. VuePress超详细简单教程