零基础教学,用python爬虫框架“Scrapy”来解锁一个小成就
ccwgpt 2024-09-27 07:29 103 浏览 0 评论
嘿~大家好,我是小编4U:
作为一个爬虫的老手了,不知道大家有没有一种感觉:要写出一个完整的爬虫程序需要做很多琐碎的工作。比如,要针对不同的网站制定不同的解析方式;要导入不同功能的模块;还要编写各种爬取流程的代码。我们在日常工作中会使用PPT模板来制作PPT。那么有没有一个现成的爬虫模板,让我们能够改之即用,也就是说对这个模板进行适当的修改,就能完成一个爬虫项目的开发呢?
那就让我们来一起学习一下Scrapy这个nb的框架
(只要认真学,绝对能拿下)
一
什么是Scrapy
在学习python的过程中,我们用到了许多的模块,他们有不同的功能,比如:
- 1. requests模块:进行请求
- 2. csv模块:储存数据
而在Scrapy框架里面,我们不需要做怎么多,因为在这个框架里面都能自动实现,下面,我们就来了解Scrapy的基础知识,包括Scrapy的结构及其工作原理;
上面的这张图是Scrapy的整个结构。你可以把整个Scrapy框架当成是你所在的部门。最中心位置的Scrapy Engine(引擎)就是你所在部门的大boss,负责统筹规划你这个部门的四大职能。
- Scheduler(调度器) 主要负责处理引擎发送过来的requests对象(即网页请求的相关信息集合,包括params,data,cookies,request headers…等),会把请求的url以有序的方式排列成队,并等待引擎来提取(功能上类似于gevent库的queue模块)。
- Downloader(下载器) 则是负责处理引擎发送过来的requests,进行网页爬取,并将返回的response(爬取到的内容)交给引擎。它对应的是爬虫流程【获取数据】这一步。
- Spiders(爬虫) 主要任务是创建requests对象和接受引擎发送过来的response(Downloader部门爬取到的内容),从中解析并提取出有用的数据。它对应的是爬虫流程【解析数据】和【提取数据】这两步。
- Item Pipeline(数据管道) 负责存储和处理Spiders提取到的有用数据。这个对应的是爬虫流程【存储数据】这一步。
- Downloader Middlewares(下载中间件) 它的工作相当于下载器的助手,比如会提前对引擎发送的诸多requests做出处理。
- Spider Middlewares(爬虫中间件) 它的工作则相当于爬虫的助手,比如会提前接收并处理引擎发送来的response,过滤掉一些重复无用的东西。
二
Scrapy的工作原理
在Scrapy爬虫部门里,每个成员都各司其职,互相配合,这套运行流程的逻辑很简单,其实就是:引擎大boss说的话就是最高需求!看下面的对话:
- ScrapyEngine: 伙计们,今天咱们要爬什么呢?
- Spiders: 爬取一个url:htpps://…,我已经分装成requests了
- ScrapyEngine: 调度器,配合Spiders的工作。把requests都放进队列
- 调度器: 收到!
- ScrapyEngine: 下载器,把这些requests爬下来,爬取结果发给我
- 下载器: 下载器:收到,现在开始处理
- 下载器: 已完成,现在把response发给你。
- ScrapyEngine: Spiders, 我已经把response发给你,请尽快解析和处理
- Spiders: 收到。已完成,提取出来的Item已经发送给你了。
- ScrapyEngine: 数据管道,把Spider这些Otem处理一下。
- 数据管道: 收到,现在开始处理。
从上面的对话可以看出Scrapy框架的工作原理。也有许多的优势和好处:
- 在使用 Scrapy 的时候。我们不需要去关心爬虫的每个流程。
- 并且Scrapy中的网络请求都是默认异步模式,请求和返回都会由引擎去自动分配处理。
- 如果某个请求出现异常,框架也会帮我们做异常处理,跳过这个异常的请求,继续去执行后面的程序。
- 所以说,我们使用 Scrapy 可以省掉很多的时间和工作
三
Scrapy的用法
初学的小伙伴在没搞懂原理之前,先别急着看下面的内容,试着把原理搞懂再来做项目。
我们在了解完Scrapy的结构和工作原理后,我们就来试着爬一爬——豆瓣Top250的图书。
01
明确目标:
先来查看一下即将要爬取的网址 :https://book.douban.com/top250
豆瓣Top250图书一共有10页,每页有25本书籍。我们的初步目标是:先只爬取前三页书籍的信息,总共是 25 x 3 = 75 本,包含书名、出版信息、书籍评分。
02
分析目标:
接下来就是要分析爬取网站的网页结构, 首先得判断这些信息被存在了哪里,为了防止出错,大家最好跟着操作,按F12打开快乐爬虫模式,点开Network
- 刷新页面,然后点击第0个请求top250,看Response.
- 我们能在里面找到书名、出版信息,说明我们想要的书籍信息就藏在这个网址的HTML里。
- 我们能在里面找到书名、出版信息,说明我们想要的书籍信息就藏在这个网址的HTML里。
- 接着,我们就来具体观察一下这个网站,因为它是带分页的。
- 所以点击翻到豆瓣Top250图书的第2页。
- https://book.douban.com/top250?start=25
- 我们可以看到,网址发生了变化,后面多了 ?start=25。现在的你,应该就能猜到后面的数字应该是代表一页的25本书籍吧?我们还可以看一下第三页,来验证一下
事实证明,我们猜对了。每翻一页,网址后面的数字都会增加25,说明这个start的参数就是代表每页的25本书籍。
也就是表达只要改变 ?start=后面的数字(翻一页加25),我们就能得到每一页的网址。
网页我们已经得到,接下来就是如何去得到所要爬取的内容了
还是是右击打开“检查”工具,点击 Elements,再点击光标,把鼠标依次移到书名、出版信息、评分处,就能在HTML里找到这些书籍信息。如下图,《红楼梦》的书籍信息就全部放在 table width="100%"标签里
但是问题出现了:
- 其实每一页的25本书籍信息都分别藏在了一个 table width="100%"标签里。不过这个标签没有 class属性,也没有id属性,不方便我们提取信息。
- 那怎么办呢?我们得继续再找一个既方便我们提取,又能包含所有书籍信息的标签。
- 我们可以看看 table width="100%"标签下的 tr class="item"元素,好像刚好都能满足我们的要求,既有 class属性,又包含了书籍的信息。
最后来总结一下:
我们只要取出 <tr class="item"> 元素下 <a> 元素的title属性的值、<p class="pl">元素,<span class="rating_nums">元素,就能得到书名、出版信息和评分的数据。
03
代码实现
接下来会涉及到很多Scrapy的用法,如果想学会的话,请你一定要认真地看!
(1).Scrapy的安装和文件生成
使用 conda 安装 Scrapy,运行:
conda install -c conda-forge scrapy
或者,可以从pypi安装scrappy及其依赖项
pip install Scrapy
安装完成后,要在本地电脑打开一个你要保存的文件
再框内输入cmd,然后回车
就能跳转到对于文件的终端;
然后,再输入一行能帮我们创建Scrapy项目的命令:
scrapy startproject douban,douban 就是Scrapy项目的名字。回车,一个Scrapy项目就创建成功了,只要一步一步来,肯定不会出错的
下载完成后,可以看到有这些文件
Scrapy项目里每个文件都有它对应的具体功能。例如:
- settings.py 是scrapy里的各种设置、
- items.py 是用来定义数据的、
- pipelines.py 是用来处理数据的,
它们对应的就是Scrapy的结构中的Item Pipeline(数据管道)。
其中最重要的是spiders是放置爬虫的目录。我们可以在spiders这个文件夹里创建爬虫文件。我们来把这个文件,命名为Book_douban_Top250。后面的大部分代码都需要在这个Book_douban_Top250.py文件里编写。
(2).Scrapy核心代码
注意!前方高能部分了,请系好安全带!勿跟丢了!
导入BeautifulSoup用于解析和提取数据; 导入scrapy是待会我们要用创建类的方式写这个爬虫,我们所创建的类将直接继承scrapy中的scrapy.Spider类。这样,有许多好用属性和方法,就能够直接使用。
接着我们开始编写爬虫的核心代码。
在Scrapy中,每个爬虫的代码结构基本都如下所示:
- import scrapy
- import bs4
- class DoubanSpider(scrapy.Spider):
- # 定义一个爬虫类DoubanSpider
- name = 'book_douban'
- # name是定义爬虫的名字,这个名字是爬虫的唯一标识。
- # name = 'book_douban'意思是定义爬虫的名字为book_douban。
- # 等会我们启动爬虫的时候,要用到这个名字。
- allowed_domains = ['book.douban.com']
- # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。
- # 如果网址的域名不在这个列表里,就会被过滤掉。
- start_urls = ['https://book.douban.com/top250?start=0']
- # start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。
- # 并且allowed_domains的设定对start_urls里的网址不会有影响。
- def parse(self, response):
- # parse是Scrapy里默认处理response的一个方法。
- print(response.text)
是不是觉得和之前自己动手写爬虫的完全不一样了呢?怎么连
requests.get()
都没有了呢?其实在框架里,我们并不需要写这一句。scrapy框架会为我们做这件事,写好请求后,接下来你就可以直接写对 response
如何做处理,我会在后面做出示例。
在上面我们已经找到了网站的规律,我们直接用for循环得到每个网址:
https://book.douban.com/top250?start=(页数-1)*25 ,代码如下:
- for x in range(3):
- # 获取网址,添加到start_urls
- url = f'https://book.douban.com/top250?start={x * 25}'
- start_urls.append(url)
我们只先爬取豆瓣Top250前3页的书籍信息,接下来,只要再借助DoubanSpider(scrapy.Spider)中的 parse 方法处理 response,借助 BeautifulSoup 来取出我们想要的书籍信息的数据。Let`s go
- def parse(self, response):
- #parse是默认处理response的方法。
- bs = bs4.BeautifulSoup(response.text,'html.parser')
- #用BeautifulSoup解析response。
- datas = bs.find_all('tr',class_="item")
- #用find_all提取<tr class="item">元素,这个元素里含有书籍信息。
按照流程,接下来就应该保存数据了,但是在Scrapy里面有点不一样哈。
spiders(如Book_douban_Top250.py)只干 spiders 应该做的事。对数据的后续处理,另有其他“部门”负责。在 scrapy中,我们会专门定义一个用于记录数据的类。定义这些数据类的python文件,正是items.py。
接下来让我们在 items.py 中编写这部分的代码:
- import scrapy
- # 导入scrapy
- class BookDoubanItem(scrapy.Item):
- # 定义一个类BookDoubanItem,它继承自scrapy.Item
- title = scrapy.Field()
- # 定义书名的数据属性
- publish = scrapy.Field()
- # 定义出版信息的数据属性
- score = scrapy.Field()
- # 定义评分的数据属性
scrapy.Field()这行代码实现的是,让数据能以类似字典的形式记录。但它却并不是dict,它的数据类型是我们定义的DoubanItem,属于“自定义的Python字典”。
- def parse(self, response):
- # parse是默认处理response的方法
- bs = bs4.BeautifulSoup(response.text, 'html.parser')
- # 用BeautifulSoup解析response
- datas = bs.find_all('tr', class_="item")
- # 用find_all提取<tr class="item">元素,这个元素里含有书籍信息
- for data in datas:
- # 遍历data
- item = BookDoubanItem()
- # 实例化DoubanItem这个类
- item['title'] = data.find_all('a')[1]['title']
- # 提取出书名,并把这个数据放回DoubanItem类的title属性里
- item['publish'] = data.find('p', class_='pl').text
- # 提取出出版信息,并把这个数据放回DoubanItem类的publish里
- item['score'] = data.find('span', class_='rating_nums').text
- # 提取出评分,并把这个数据放回DoubanItem类的score属性里。
- print(item['title'])
- # 打印书名
- yield item
- # yield item是把获得的item传递给引擎
当我们需要记录一次数据的时候,比如前面在每一个最小循环里,都要记录“书名”,“出版信息”,“评分”。我们会实例化一个item对象,利用这个对象来记录数据。一个对象对应一次数据
在Scrapy框架里,每一次当数据完成记录,它会离开spiders,来到Scrapy
Engine(引擎),引擎将它送入Item Pipeline(数据管道)处理。这里,要用到yield语句。
yield语句你可能还不太了解,这里你可以简单理解为:它有点类似return,不过它和return不同的点在于,它不会结束函数,且能多次返回信息。
(3).Scrapy思路整理
让我们理一下思路:
- 爬虫(Spiders)会把豆瓣的10个网址封装成requests对象,引擎会从爬虫(Spiders)里提取出requests对象,再交给调度器(Scheduler),让调度器把这些requests对象排序处理。
- 然后引擎再把经过调度器处理的requests对象发给下载器(Downloader),下载器会立马按照引擎的命令爬取,并把response返回给引擎。
- 紧接着引擎就会把response发回给爬虫(Spiders),这时爬虫会启动默认的处理response的parse方法,解析和提取出书籍信息的数据,使用item做记录,返回给引擎。引擎将它送入Item Pipeline(数据管道)处理。
如果现在运行还是会报错,原因在于Scrapy里的默认设置没被修改。比如我们需要修改请求头(User-Agent需要设置)。点击settings.py文件,你能在里面找到如下的默认设置代码:
在这里我们把USER _AGENT的注释取消(删除#),然后替换掉user-agent的内容,就是修改了请求头。
又因为Scrapy是遵守robots协议的,如果是robots协议禁止爬取的内容,Scrapy也会默认不去爬取,所以我们还得修改Scrapy中的默认设置
把ROBOTSTXT_OBEY=True改成ROBOTSTXT_OBEY=False,就是把遵守robots协议换成无需遵从robots协议,这样Scrapy就能不受限制地运行。
最后来看一下Book_douban_Top250.py的完整代码:
- import scrapy
- import bs4
- from ..items import BookDoubanItem
- class DoubanSpider(scrapy.Spider):
- # 定义一个爬虫类DoubanSpider
- name = 'book_douban'
- # name是定义爬虫的名字,这个名字是爬虫的唯一标识。
- # name = 'book_douban'意思是定义爬虫的名字为book_douban。
- # 等会我们启动爬虫的时候,要用到这个名字。
- allowed_domains = ['book.douban.com']
- # allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。
- # 如果网址的域名不在这个列表里,就会被过滤掉。
- start_urls = ['https://book.douban.com/top250?start=0']
- # start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。
- # 并且allowed_domains的设定对start_urls里的网址不会有影响。
- for x in range(3):
- url = f'https://book.douban.com/top250?start={x * 25}'
- start_urls.append(url)
- def parse(self, response):
- # parse是默认处理response的方法
- bs = bs4.BeautifulSoup(response.text, 'html.parser')
- # 用BeautifulSoup解析response
- datas = bs.find_all('tr', class_="item")
- # 用find_all提取<tr class="item">元素,这个元素里含有书籍信息
- for data in datas:
- # 遍历data
- item = BookDoubanItem()
- # 实例化DoubanItem这个类
- item['title'] = data.find_all('a')[1]['title']
- # 提取出书名,并把这个数据放回DoubanItem类的title属性里
- item['publish'] = data.find('p', class_='pl').text
- # 提取出出版信息,并把这个数据放回DoubanItem类的publish里
- item['score'] = data.find('span', class_='rating_nums').text
- # 提取出评分,并把这个数据放回DoubanItem类的score属性里。
- print(item['title'])
- # 打印书名
- yield item
- # yield item是把获得的item传递给引擎
(4).Scrapy运行
想要运行Scrapy有两种方法:
- 一种是在本地电脑的终端跳转到scrapy项目的文件夹,然后输入命令行:scrapy crawl book_douban(book_douban就是我们爬虫的名字)。
- 另一种运行方式需要我们在最外层的大文件夹里新建一个main.py文件(与scrapy.cfg同级)。
代码:
- from scrapy import cmdline
- #导入cmdline模块,可以实现控制终端命令行
- cmdline.execute(['scrapy','crawl','book_douban'])
- #用execute()方法,输入运行scrapy的命令
大功告成,来运行一下看看效果。
在终端可以看到所爬取的数据,Nice!!
在这里是没有保存数据,因为存储数据需要修改pipelines.py文件。
因为内容过多~所以呢,等过几天再继续更新,教大家如何保存数据。
Scarpy好用归好用,但是对于小白来说学习起来还是有一定难度滴~
但是我相信你是最棒的,特别是在看完本次的教程后,在通过自己的摸索,一定能成功。
————————————————
CONTACT US / 联系我们
VX/官方公众号
乐搏软件测试
头条号/官方账号
乐搏软件测试
WEIBO/官方微博
乐搏软件学院
TIKTOK/官方抖音
软件测试大乐er
BILIBILI/哔哩哔哩
乐搏软件测试
喜马拉雅/官方账号
乐搏软件测试
点击底部 “ 点赞 + 在看 ” 这个秋天会有幸运降临哦!
相关推荐
- css布局方案汇总(28个实例图文并茂)
-
简介布局在我们前端日常开发来说是非常重要的,一个好的布局能简化代码的同时还能提高网页的性能。常见的布局方法有浮动(float)布局、绝对定位(position)布局、表格布局(table)、弹性(fl...
- 十款免费的CSS框架加速Web开发
-
Pure这是Yahoo最新推出的一款CSS框架,它只有HTML和CSS,没有使用任何JavaScript语言。总大小只有4.4kb,但功能却非常丰富,支持响应式样式和各种导航、表格、表单、按钮、网格和...
- Tailwind CSS 是不是目前世上最好的CSS框架?
-
转载说明:原创不易,未经授权,谢绝任何形式的转载今天看了一篇国外大佬对TailwindCSS的看法,在这里分享给大家,看看大家是否赞同,以下是其相关内容的整理,由于翻译水平有限,欢迎大家讨论和指...
- 下一代 CSS 框架:Mojo CSS,为何如此受欢迎?
-
TailwindCSS推出即受到广大开发者的欢迎,当前Githubstar数已达77.8k。它是一个功能类优先(utility-first)的CSS框架,它提供了一系列功能类,让开发者...
- 常见的几种摄影构图方式
-
摄影构图,是一种在摄影画面中表现结构美、形式美的方式。构图能让摄影主体更加突出,画面更加有序。所以说,构图在摄影中是非常重要的一个环节。无论是前期构图还是后期构图,摄影者都要对构图有一个比较深的了解。...
- 风光摄影10大构图技巧,会用构图,照片更容易好看
-
风光摄影10大构图技巧,会用构图,照片更容易好看先解释一下,为什么会使用构图之后,照片更容易好看?因为,构图是根据很多好看的照片,总结出来的技巧,使用这些构图技巧,就相当于站在了巨人的肩膀上,也就是用...
- 掌握框式构图的摄影技巧,会让摄影爱好者的作品更有魅力!
-
很多摄影爱好者都知道摄影构图中有个框式构图,但大多数人对框式构图的摄影技巧,却一知半解。所以摄影爱好者们有必要更全面、深入的了解,并掌握框式构图,会对你摄影水平的提高更有帮助。【欢迎点击上方关注:金立...
- 这个构图很简洁,但为什么不耐看?
-
摄影爱好者最常犯的错就是过于复杂、主体不明确,但当遇到简单的场景往往又会出现单调、不耐看的状况。为什么会这样?说白了还是观察力不够。下面是本周的摄影入围习作,我们一起来看看这些照片中主体、陪体以及背景...
- 初学者需要记牢的八种常用构图法
-
作者:冯海军摄影中,构图很关键,决定照片是否成功,所以在构图上要加以重视和推敲,虽然说构图无定法,但是也有很多的规律可循,以下列举几种常用构图,会对初学者有很大的帮助。多彩刘卫洲摄苏州姑苏俱乐部(...
- 构图这件事不难!掌握14种构图模式就稳了
-
如果说视觉元素是视觉信息的载体,那么构图就是视觉元素的载体。没有适当形式的构图对视觉元素有机、有序地承载,平面设计将无法传达预定的设计意图和视觉信息。因此,对于平面设计而言,构图是平面设计不可或缺的重...
- 框架构图如何使用?
-
1分钟教你用手机拍大片。今天我们利用框架构图,在不同的运镜方法下拍摄。·首先将手机贴近地面,拍摄人物走过的画面。·然后利用3D效果的背景衬托,将手机贴近地面,以低角度仰拍人物。·最后我们用高清画质来呈...
- 面构图的5种超实用的构图形式 前景构图,框架构图,填充构图
-
面构图的5种超实用的构图形式。为什么有的人拍摄的照片好看又舒适?仔细观察会发现他们善用构图。大家好,今天带大家了解摄影中5种超实用的面构图形式。·一、前景构图。前景是构图中的神奇要素,可以提升照片的表...
- 一看就懂!跟着马格南的大师学构图
-
马格南图片社是迄今为止全球最重要的摄影图片社,其网站包涵了太多经典的名字和照片。细细品味这些经典图片,能够学到很多有用的构图手法。跟着大师走,总不会错吧?前后景的运用这似乎是非常常见的一种手法,仔细看...
- 这才是框架构图,有想法!能给你启发么?
-
框架构图大家并不陌生,但并不是有一个框就行了。框架构图用得不好,就很死板生硬,给人感觉很假。如果你理解透了,拍出的作品不会单调。今天就给大家分享一下框架构图,你看看有哪些妙用?1.广角与长焦的应用长焦...
- 7B小模型写好学术论文,新框架告别AI引用幻觉
-
ScholarCopilot团队投稿量子位|公众号QbitAI学术写作通常需要花费大量精力查询文献引用,而以ChatGPT、GPT-4等为代表的通用大语言模型(LLM)虽然能够生成流畅文本,但...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 若依框架 (41)
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- bootstrap框架 (43)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- scrapy框架 (52)
- beego框架 (42)
- java框架spring (43)
- grpc框架 (55)
- 前端框架bootstrap (42)
- orm框架有哪些 (43)
- ppt框架 (48)
- 内联框架 (52)
- winform框架 (46)
- gui框架 (44)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle v (42)
- oracle字符串长度 (48)
- oracle提交事务 (47)