文章目录

  • 一、Scrapy 框架准备
  • 二、快速启动项目
    • 1、创建项目结构
    • 2、创建爬虫
    • 3、更改设置
    • 4、爬虫类分析
    • 5、编写启动脚本
  • 三、爬虫实战
    • 1、初步探索
    • 2、优化数据模型
    • 3、优化数据存储方式
    • 4、爬取多个页面

爬虫系列文章:

  • Python:使用爬虫获取中国最好的大学排名数据(爬虫入门)
  • Python:使用爬虫获取世界大学学术排名存储到 Excel 并作可视化输出
  • 多线程爬虫入门及问题解决(爬取表情包)

今天来介绍一下 Python 的一个爬虫框架Scrapy ,类似的还有 Portia Crawley

本项目源码地址:https://github.com/wsuo/pythonHomework/tree/master/demo

一、Scrapy 框架准备

首先是安装爬虫这个框架:

pip install scrapy

官方文档:https://docs.scrapy.org/en/latest/

如果是 Windows 下安装的,还需要安装一下这个:

pip install pypiwin32

如果是 Ubuntu 上安装,需要提前安装这个:

sudo apt-get install python3-dev build-essential python3-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev

二、快速启动项目

以爬取糗事百科网站为例:https://www.qiushibaike.com/

可以分为以下四步:

scrapy startproject demo
cd demo
scrapy genspider qsbk qiushibaike.com
scrapy crawl qsbk

1、创建项目结构

创建一个名为 demo 的项目,该命令仅仅是创建项目结构,你完全可以自己创建,只不过自动生成方便一些:

scrapy startproject demo

使用 PyCharm 打开一个空的文件夹,然后进入终端输入命令即可:

项目结构如图:

  1. items.py:用来存放爬虫爬取下来数据的模型
  2. middlewares.py:用来存放各种中间件的文件。
  3. pipelines.py:用来将items的模型存储到本地磁盘中。
  4. settings.py:本爬虫的一些配置信息(比如请求头、多久发送一次请求、ip代理池等)。
  5. scrapy.cfg:项目的配置文件
  6. spiders包:以后所有的爬虫,都是存放到这个里面。

2、创建爬虫

先执行进入到工作目录:

cd demo

然后执行命令创建爬虫:

scrapy genspider qsbk qiushibaike.com

然后就会自动生成一个文件qsbk.py

3、更改设置

首先我们要更改一下设置项,为了能够爬到我们想要的数据,我们这里 顶风作案 一下:

修改 ROBOTSTXT_OBEY = False

然后加上请求头的 User-Agent,伪装为浏览器访问:

DEFAULT_REQUEST_HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.116 Safari/537.36',
}

4、爬虫类分析

下面我们来看一下爬虫类:

name = 'qsbk'  # 运行的时候输入这个名字,比如
allowed_domains = ['qiushibaike.com']  # 允许的域名
start_urls = ['http://qiushibaike.com/']  # 开始的 url

我们先来试一下:

class QsbkSpider(scrapy.Spider):name = 'qsbk'  # 运行的时候输入这个名字allowed_domains = ['qiushibaike.com']  # 允许的域名start_urls = ['https://www.qiushibaike.com/text/page/1/']  # 开始的 urldef parse(self, response):print('-'*40)print(response)print(type(response))print('-'*40)

运行一下:scrapy crawl qsbk 就可以看到结果了。

<200 https://www.qiushibaike.com/text/page/1/>
<class 'scrapy.http.response.html.HtmlResponse'>

类型为 HtmlResponse

追踪这个类的父类:

可以看到有 xpath 的方法,说明我们可以使用 xpath 解析响应信息。

编写如下代码:

def parse(self, response):content = response.xpath('//div[@class="content"]')print('-'*40)print(response)print(type(content))print(type(response))print('-'*40)

输出:

追踪类SelectorList,找到selector类:

观察该类的方法。

比较重要的方法就是 extract方法可以将 SelectorList类型的转化为列表类型,并且里面装的是字符串,extract_first方法是获取第一个元素。

5、编写启动脚本

由于每次都要输入命令启动挺麻烦的,所以我们可以使用脚本文件执行命令行的命令。

创建一个start.py文件,随便在哪里创建都可以;

内容如下:

from scrapy import cmdlinecmdline.execute(['scrapy', 'crawl', 'qsbk', '--nolog'])

三、爬虫实战

我们先初步的探索,然后慢慢的优化。

1、初步探索

继续上一步的操作,我们在爬虫类QsbkSpider中继续写逻辑。

先来获取一下作者的名称小试牛刀一下,编写代码:

class QsbkSpider(scrapy.Spider):name = 'qsbk'  # 运行的时候输入这个名字allowed_domains = ['qiushibaike.com']  # 允许的域名start_urls = ['https://www.qiushibaike.com/text/page/1/']  # 开始的 urldef parse(self, response):divs = response.xpath('//div[@class="col1 old-style-col1"]/div')for div in divs:author = div.xpath('./div[@class="author clearfix"]//h2/text()').get().strip()print(author)

查看输出结果:

说明这是可以的,下面我们继续爬取后面的内容,比如爬取段子的内容。

content = ''.join(div.xpath('.//div[@class="content"]/span[1]/text()').getall()).strip()

yield 的作用是将函数作为一个生成器返回,以后遍历的时候就会把数据一个一个的拿过去

def parse(self, response):divs = response.xpath('//div[@class="col1 old-style-col1"]/div')for div in divs:author = div.xpath('.//h2/text()').get().strip()content = ''.join(div.xpath('.//div[@class="content"]/span[1]/text()').getall()).strip()# yield 的作用是将函数作为一个生成器,以后遍历的时候就会把数据一个一个的拿过去yield {'昵称': author, '段子内容': content}

然后我们可以存储到本地,这就是需要到管道中执行了,所以打开DemoPipeline类:

class DemoPipeline(object):def process_item(self, item, spider):return itemdef open_spider(self, spider):print('爬虫开始')def close_spider(self, spider):print('爬虫结束')

后面两个方法默认是没有的,但是如果我们有文件操作最好可以放在这里面。

但是在使用之前,我们必须要先到配置文件中打开管道:

后面这个值越小越先执行。

编写代码:

import jsonclass DemoPipeline(object):def process_item(self, item, spider):json.dump(item, self.file, ensure_ascii=False, indent=4)self.file.write('\n')return itemdef open_spider(self, spider):self.file = open('dz.json', 'a', encoding='utf-8')print('爬虫开始')def close_spider(self, spider):self.file.close()print('爬虫结束')

执行结果:

2、优化数据模型

我们之前使用的是自己造的一个字典在爬虫类和管道之间传输,但是更好的做法是使用数据模型,下面我们来实现一下。

定义一个类DemoItem

class DemoItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()author = scrapy.Field()content = scrapy.Field()

然后我们在爬虫类中引入这个模型:

import scrapy
# noinspection PyUnresolvedReferences
from demo.items import DemoItemclass QsbkSpider(scrapy.Spider):name = 'qsbk'  # 运行的时候输入这个名字allowed_domains = ['qiushibaike.com']  # 允许的域名start_urls = ['https://www.qiushibaike.com/text/page/1/']  # 开始的 urldef parse(self, response):divs = response.xpath('//div[@class="col1 old-style-col1"]/div')for div in divs:author = div.xpath('.//h2/text()').get().strip()content = ''.join(div.xpath('.//div[@class="content"]/span[1]/text()').getall()).strip()# yield 的作用是将函数作为一个生成器,以后遍历的时候就会把数据一个一个的拿过去yield DemoItem(author=author, content=content)

好处就是:解耦,约定数据种类,更规范。

但是在管道中获取的时候会有问题,因为他获取的是一个 DemoItem 类型的参数,我们要把它转化为字典类型。

json.dump(dict(item), self.file, ensure_ascii=False, indent=4)

3、优化数据存储方式

优化存储方式肯定要修改管道中的代码,所以我们先注释掉之前写的代码。

使用 scrapy 自带的 JSON 持久化方式。

from scrapy.exporters import JsonItemExporterclass DemoPipeline(object):def __init__(self):self.file = open('dz.json', 'wb')self.exporter = JsonItemExporter(self.file, ensure_ascii=False, encoding='utf-8')def open_spider(self, spider):print('爬虫开始了')# 使用二进制打开self.exporter.start_exporting()def process_item(self, item, spider):self.exporter.export_item(item)return itemdef close_spider(self, spider):self.exporter.finish_exporting()self.file.close()print('爬虫结束了')

注意这里必须是文件打开的方式必须是 wb 而且不能指定编码格式。

这样执行的结果就是装在一个列表当中了。

它的执行流程其实就是先将数据塞到一个列表当中,然后调用finish_exporting()写入文件中。

所以他有一个缺陷就是如果 item 比较大的话,他的列表也比较大,一直在内存中就会比较耗内存。

所以我们可以使用JsonLinesItemExporter这个类,他就是不缓存到一个列表当中,直接一行一行的写入文件。

代码如下:

class DemoPipeline(object):def __init__(self):self.file = open('dz.json', 'wb')self.exporter = JsonLinesItemExporter(self.file, ensure_ascii=False, encoding='utf-8')def open_spider(self, spider):print('爬虫开始了')def process_item(self, item, spider):self.exporter.export_item(item)return itemdef close_spider(self, spider):self.file.close()print('爬虫结束了')

结果如下:
还有很多文件格式的保存方法,比如 xmlcsvpickel 等等,这里就不再一一演示了。

4、爬取多个页面

我们之前爬的都是单页面,那么怎么才能爬取多页面呢?

我们再来分析一下页面结构:

可以看到最后一个 li 标签中就是页数,但是有一点要注意的就是到最后一页的时候要有一个判断。

我们使用 xpath 来获取 href 的值:

在爬虫类中编写代码:

class QsbkSpider(scrapy.Spider):name = 'qsbk'  # 运行的时候输入这个名字allowed_domains = ['qiushibaike.com']  # 允许的域名start_urls = ['https://www.qiushibaike.com/text/page/1/']  # 开始的 urlbase_domain = 'https://www.qiushibaike.com'def parse(self, response):divs = response.xpath('//div[@class="col1 old-style-col1"]/div')for div in divs:author = div.xpath('.//h2/text()').get().strip()content = ''.join(div.xpath('.//div[@class="content"]/span[1]/text()').getall()).strip()# yield 的作用是将函数作为一个生成器,以后遍历的时候就会把数据一个一个的拿过去yield DemoItem(author=author, content=content)next_url = response.xpath('//ul[@class="pagination"]//li[last()]/a/@href').get()if not next_url:returnelse:yield scrapy.Request(self.base_domain + next_url, callback=self.parse)

我们在设置页面设置下载的延时,这样的话可以控制爬的速度,因为太快的话容易被发现,而且还有可能把别人服务器搞垮了:

执行结果:

当然这样不是最好的解决方案,后续文章会讲解 CrawlSpider 类的使用。


参考链接:

  • https://www.bilibili.com/video/BV124411A7Ep
  • https://docs.scrapy.org/en/latest/

Python爬虫:Scrapy 框架快速入门及实战演练相关推荐

  1. Python Scrapy中文教程,Scrapy框架快速入门!

    谈起爬虫必然要提起 Scrapy 框架,因为它能够帮助提升爬虫的效率,从而更好地实现爬虫. Scrapy 是一个为了抓取网页数据.提取结构性数据而编写的应用框架,该框架是封装的,包含 request ...

  2. Python爬虫 scrapy框架爬取某招聘网存入mongodb解析

    这篇文章主要介绍了Python爬虫 scrapy框架爬取某招聘网存入mongodb解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 创建项目 sc ...

  3. python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取

    python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取 前言 本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行政策文本爬虫进行记录.用于个人爬虫学习记 ...

  4. Python爬虫—Scrapy框架—Win10下载安装

    Python爬虫-Scrapy框架-Win10下载安装 1. 下载wheel 2.下载twisted 3. 下载pywin32 4. 下载安装Scrapy 5. 创建一个scrapy项目 6. fir ...

  5. Python爬虫-Scrapy框架(四)- 内置爬虫文件 - 4.2 初探Crawl Spider

    Python爬虫-Scrapy框架(四)- 内置爬虫文件 - 4.2 初探Crawl Spider 写在前面 初探Crawl Spider 创建Crawl Spider项目 对比Basic与Crawl ...

  6. python 爬虫Scrapy框架入门

    简单介绍Scrapy框架 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取. Scrapy使用了Twisted异步网络框架,可以加快我们的 ...

  7. Python爬虫——Scrapy框架(附有实战)

    大家好!我是霖hero 有一天,我在逛街,突然被一声靓仔打断了我的脚步,回头一看,原来是水果摊阿姨叫我买水果,说我那么靓仔,便宜一点买给我,自恋的我无法拒绝阿姨的一声声靓仔,于是买了很多水果回家,家人 ...

  8. python爬虫——scrapy框架(介绍)

    一.scrapy介绍 Scrapy是用纯Python实现的一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能快速的抓取. Scrapy使用了 Twisted[ˈtwɪ ...

  9. python爬虫scrapy框架教程_Python爬虫教程-30-Scrapy 爬虫框架介绍

    从本篇开始学习 Scrapy 爬虫框架 Python爬虫教程-30-Scrapy 爬虫框架介绍 框架:框架就是对于相同的相似的部分,代码做到不出错,而我们就可以将注意力放到我们自己的部分了 常见爬虫框 ...

最新文章

  1. Ubuntu 16.04安装NASM汇编IDE-SASM
  2. Biztalk 在流程中定义将消息保存为文件的文件名
  3. bootstrap-按钮(按钮工具栏)
  4. UA MATH567 高维统计I 概率不等式1 Hoeffding不等式与Chernoff不等式
  5. LwIP 之二 网络接口 netif(ethernetif.c、netif.c)
  6. Java中ArrayList和LinkedList区别 时间复杂度 与空间复杂度
  7. P5502-[JSOI2015]最大公约数【分治】
  8. Date动态获取时间
  9. MPLS/×××江湖恩仇录笔记
  10. 共享会话怎么设置没访问自动断开_谁总结的JavaWeb会话技术了?太全面了...
  11. VS2010 在Win 7 附加w3wp.exe进程进行调试
  12. Python入门学习笔记05(内置函数)
  13. 学习笔记-Speed-Win
  14. 三菱plc软件测试程序com端口,三菱plc编程软件com端口不能保存
  15. CentOS6.5下lv调整空间大小
  16. SQL中字符串拼接方法(MySQL,SQLServer)
  17. Android 点击按钮出现弹窗
  18. 华为服务器linux光驱名称,华为服务器通过mgmt口挂载光盘装系统及Linux系统rescue模式下修复内核...
  19. win10系统幻灯片播放卡顿
  20. 浏览器显示网页的原理 多种情况方式

热门文章

  1. Protel 99 SE使用心得
  2. Logistics回归模型
  3. printf中如何输出长整型?
  4. centos 7 vmstat命令详解
  5. openCV中二值化图像的方法
  6. python多线程破解压缩包_我用 Python 破解了同事的加密压缩包!
  7. word 表格不跨行断页
  8. [机器学习]概率图模型
  9. android 微信摇一摇功能实现,android 类似微信的摇一摇功能实现思路及代码
  10. 按音量键和按Fn+音量键,笔记本电脑均没反应的解决办法