python爬虫(二十)scrapy介绍、框架、工作流程及步骤、爬取豆瓣主页标签

您所在的位置:网站首页 工作流程简单 python爬虫(二十)scrapy介绍、框架、工作流程及步骤、爬取豆瓣主页标签

python爬虫(二十)scrapy介绍、框架、工作流程及步骤、爬取豆瓣主页标签

2024-07-11 02:57| 来源: 网络整理| 查看: 265

scrapy介绍

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取,Scrapy使用了Twisted异步网络框架,可以加快我们的下载速度。 scrapy是异步爬虫的框架,是爬虫必备的技术,很少有语言有专门的框架进行爬虫,python中的scrapy框架是专门用于爬虫的;让爬虫程序更稳定,效率更高,scrapy框架的很多内容都是封装好的;配置和可扩展性很高,有了固定的框架,直接去添加内容和调用就可以了;是基于异步的,内部封装了Twisted(曲折),实现逻辑非常复杂,采取了大量的闭包,以高阶函数(以函数为返回值或是以函数对象为参数的)为基础,大的函数里嵌套了小的函数,函数内部要去引用外部函数的变量,确保变量的安全性,就形成了闭包。下载速度非常快,是异步网络框架,download的原理是基于内部封装的多线程,直接调用就可以了,下载的效率也很高,内部封装了可以控制爬取速度的方法,可以通过修改配置项来达到控制爬取速度的目的。

异步和非阻塞的区别

在这里插入图片描述 同步的过程,从上往下看,只有等待蓝色函数执行完后,获取return之后再执行黄色的函数,好比一条流水线,只有把上面的事情做完了才能做下面的事情。 异步的过程,蓝色的函数并没有对黄色的函数产生影响,在蓝色向网站发起请求,在等待网站反馈的时间段里,黄色函数就可以向另外一个页面发起请求,充分利用了等待的时间,提高了爬取的效率。 异步:调用在发出之后,这个调用就直接返回,不管有无结果 非阻塞:关注的是程序在等待调用结果时的状态,指在不能立刻得到结果之前,该调用不会阻塞当前线程。

Scrapy工作流程

我们通常不会仅仅只对一个url发起请求,实现对多个页面的爬取,这时就可以把多个页面放到url list 中。从url list 中提取出url,并向其发送请求,获得相应,提取数据,解析数据,保存内容等数据的处理;然后对下一个url循环进行同样的操作。 在这里插入图片描述 有两个队列,队列1存放的是每一页的url,运行的线程从队列1中拿到url,发请求,获相应,解析每一页的数据,把解析到的数据放到队列2中(如解析图片的名字和url),然后放到下一个线程中进行下载和保存的操作。 在这里插入图片描述 scrapy是基于异步的,它的可配置性和可扩展性都很高,结构比较特殊和复杂。引擎负责整个scrapy框架的调度,无论是请求还是获取相应都要经过引擎,相当于人类的大脑。第一步,把目标url发送给引擎,引擎的下方有个爬虫程序,里有我们需要的url地址,把url地址发送给引擎,引擎只负责调度,download是个下载器;第二步引擎拿到url之后会先给调度器,调度器接收到请求的url并入列;第三步入列之后调度器给下载器,下载器连接网络之后做请求响应的操作,调度器发起请求,获得响应的结果;第四步响应的结果并不是给下载器处理的,下载器获取到响应结果之后,交给爬虫程序进行处理,爬虫程序拿到响应结果之后做数据解析处理;第五步把解析到的数据交给管道处理,管道专门做保存数据的。然后循环进行操作,直到调度器里没有url为止。 大致的工作流程:引擎会找爬虫程序要到url(可能会是多个),通过爬虫程序拿到url之后给调度器,url在调度器里入列,入列后取出其中一个url返回下载器进行发送请求,获取相应,把相应结果给爬虫程序做解析的处理,最后爬虫程序把解析好的数据给管道做保存操作,这个过程循环进行,直到调度器中没有任何的url,就会停止。 在这里插入图片描述 1.爬虫程序发送url给引擎,2.引擎发送url给调度器入列,3.调度器给引擎一个爬取的url,4.引擎把url通过下载中间件发送给下载器,下载器拿到url之后需要联网发送请求,获取相应,5.下载器把生成的response通过下载中间件发送给引擎,6.引擎会把接收到的response给爬虫程序解析,爬虫程序和引擎中间通过爬虫中间件进行连接,7.爬虫程序把解析好的数据之后,通过引擎发送给管道文件进行保存操作,8.通过解析的数据中可能页有新的url需要处理,继续上面的步骤。 在这里插入图片描述

名称作用实现Scrapy engine(引擎)整个框架的核心,总指挥:负责数据和信号的在不同模块间的传递scrapy已经实现Scheduler(调度器)一个队列,存放引擎发过来的request请求,接收从引擎发送来的url,进行入列的操作scrapy已经实现Downloader(下载器)发送请求,获取相应,下载把引擎发过来的requests请求,并返回给引擎scrapy已经实现Spider(爬虫文件)数据解析,处理引擎发来的response,提取数据,提取url,并交给引擎需要改写Item Pipline(管道)存储数据,处理引擎传过来的数据,比如存储需要改写Downloader Middlewares(下载中间件)位于引擎和下载器中间,用来处理它们之间的请求和相应(用的比较多),可以自定义的下载扩展,比如设置代理一般不用手写Spider Middlewares(中间件)可以自定义requests请求和进行response过滤一般不用手写爬虫中间件位于引擎和爬虫程序中间,用来处理爬虫程序的响应和输出结果以及新的请求(用的比较少)一般不用手写

框架是搭好的,内部是已经封装好的程序,爬虫文件,管道需要改写,下载中间件可能需要改写。

用scrapy爬取数据的基本步骤

第一步 创建scrapy项目,需要用到命令,scrapy startproject(固定的)+ 项目名字,开始项目后面跟项目的名字 第二部 创建爬虫程序 scrapy genspider(固定的)+爬虫文件的名字 + 爬取的范围(域名) 执行scrapy爬虫程序的命令:scrapy crawl 爬虫文件的名字

1 创建一个scrapy项目 scrapy startproject mySpider 2 生成一个爬虫 scrapy genspider demo demo.cn https://www.baidu.com/ --> baidu.com https://www.douban.com/ --> douban.com 3 提取数据 完善spider 使用xpath等 4 保存数据 pipeline中保存数据

具体步骤:点击pycham下方的Terminal进入路径界面,依次按路径输入 cd 爬虫,cd 21day ,进入到D:\PycharmProjects\爬虫\21day>路径里,然后创建mySpider的文件夹,执行命令scrapy startproject mySpider。 在这里插入图片描述 现在新的工程文件已经创建成功,同时在pycham左侧显示创建成功的文件夹 在这里插入图片描述 依次展开mySprider文件夹,出现以下文件,打开scrapy.cfg文件,里面会提示这个文件是自动创建的,有最新的帮助文档地址,以及告诉我们其他配置文件的来源及如何创建的。

在这里插入图片描述 创建好文件夹之后,下面就可以通过cd mySprider进入到文件夹内部,创建通过scrapy genspider 爬虫程序了,这里先创建豆瓣的爬虫文件,scrapy genspider db douban.com。 在这里插入图片描述 提示爬虫文件已经创建完成,我们通过mySprider,spiders目录下看到创建好的db文件。 在这里插入图片描述 创建好的db文件内,在parse函数里会有高亮提示,给出了警告,在继承父类的过程中,会有修改父类的需求,涉及到面向对象的重写和重载的概念,重写是子类对父类的实现方法进行重新的编写,此时返回值和形参都不能改变,只能修改函数里面的代码,头和尾都不能修改,也就是说外壳不能改变,内部的东西可以进行重写;重载是方法名相同,参数以及返回值类型都不一样。这里是需要对函数进行重载,对参数的个数进行了修改,出现了不一致的情况,在代码源文件中有三个参数(def parse(self, response, **kwargs):),这里只有两个,这个提示并不影响后面的爬取和程序的运行,也可以把源代码复制进去进行替代。 这时程序运行是在21day文件夹下的mySprider,如果对mySprider文件进行删除操作,会提示文件夹正在使用不能删除,可以用cd…,退出当前文件夹。 在创建的文件夹中需要修改几个常用的参数,settings.py中设置 ROBOTSTXT_OBEY、CONCURRENT_REQUESTS、DOWNLOAD_DELAY、DEFAULT_REQUEST_HEADERS、SPIDER_MIDDLEWARES、DOWNLOADER_MIDDLEWARES、ITEM_PIPELINES,打开注释就可以使用。运行程序的时候用的比较多的是爬虫、pipelines、settings文件。

用scrapy爬取豆瓣主页标签 页面分析

在页面“选电影”处,点右键检查,定位到li下的a标签内,复制“选电影”到网页源码中查看,发现网页是静态加载出来的,需要的数据在网页源码中。往上折叠一下,发现电影类别下每个标签都存放在相应的li内,所有的li都放到ul标签内,一直往上收,发现有电影、小组等多个类别放在div标签中的,而我们需要的数据标签都放在class="sid-links nav-anon"的标签内,我们要先定位到class=“sid-links nav-anon”,从网页源码中可以看到有个这样的标签,代表页面5个这样的类别。 在这里插入图片描述

在这里插入图片描述 在这里插入图片描述 爬取完成之后,发现书评和音乐人之前有空的内容,检查网页中发现中间有个购书单,点右键检查,发现购书单在a标签下的em标签里,可以对爬取的标签进行判断,如果在em标签里,就在a标签里打印。scrapy.Request(url,callback=‘解析方法’)用做翻页的处理,可以通过yield 返回,返回的是request对象。 解析完成之后,下一步进行保存,scrapy里有pipelines(管道)进行数据的保存。 1.在settings文件里把管道文件给打开,开启管道 2.去爬虫程序里,加上yield item,把需要的数据yield给管道,yield把函数变为生成器函数,直接给管道接收。在管道函数中加上开启爬虫、结束爬虫的函数,注意必须要传入参数spider。

代码实现

设置参数

setting.py LOG_LEVEL = 'WARNING' # 设置打印等级 BOT_NAME = 'mySpider' SPIDER_MODULES = ['mySpider.spiders'] NEWSPIDER_MODULE = 'mySpider.spiders' ROBOTSTXT_OBEY = True 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/92.0.4515.107 Safari/537.36 Edg/92.0.902.62' } ITEM_PIPELINES = { 'mySpider.pipelines.MyspiderPipeline': 300, }

管道文件

pipelines.py class MyspiderPipeline: def __init__(self): self.f = open('db.txt', 'w', encoding='utf-8') # 爬虫开始的方法 def open_spider(self, spider): print('爬虫开始!') def process_item(self, item, spider): # item 是从爬虫端接收到的数据,作为参数传递进去,在保存之前可以先打印看一下 # item 此时是个字典,保存的类型是txt,需要强转为字符串存入 print(item) self.f.write(str(item) + '\n') return item # 爬虫结束的方法 # spider是爬虫的对象,是爬虫的名字db def close_spider(self, spider): # print(spider.name) # db,爬虫的名字 print('爬虫结束!') self.f.close()

定义带爬取的字段名,提前做好数据封装

items.py import scrapy class MyspiderItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 可以在里面定义带爬取的字段名 title = scrapy.Field()

爬虫程序

db.py import scrapy class DbSpider(scrapy.Spider): # DbSpider类继承了scrapy.Spider name = 'db' # 爬虫的名字 allowed_domains = ['douban.com'] # 可允许的范围,网页爬取的范围,内容可以更改,内容是列表,可以添加其他内容 start_urls = ['http://douban.com/'] # 内容是列表,可以增加和修改, # 具体的解析方法,response对应的是响应结果,当成parse解析函数的参数传递到进去, # 在parse里就不用再做请求,响应的操作,只需要解析拿到的响应结果就可以了 def parse(self, response,**kwargs): # **kwargs 可加可不加,不加有警告,不影响运行 # response是html的response对象,可以用xpath方法 li_list =response.xpath('.//div[@class="side-links nav-anon"]/ul/li') for li in li_list: item = {} # item['title'] = li.xpath('.//a/text()') # print(item) # 通过 crapy crawl db 执行scrapy文件,在settings里设置打印等级和UA # {'title': []} 打印的是Selector对象,获取里面的内容 """获取Selector对象文本数据的方法: extract_first() 返回一条数据 extract 返回多条数据 get() 返回一条数据 getall() 返回多条数据 """ # item['title'] = li.xpath('./a/text()').get() # print(item) # 这是第一种启动scrapy的方法,在Terminal中输入 crapy crawl db # 第二种启动的方法,在第一个mySprider里创建start.py # 返回的数据中 书评和音乐人之间有空行,检查网页发现里面的购书单存放在a标签下的em标签里 item['title'] = li.xpath('.//a/em/text()').get() if item['title'] == None: item['title'] = li.xpath('.//a/text()').get() # print(item) yield item

启动程序

start.py from scrapy import cmdline # cmdline.execute(['scrapy', 'crawl', 'db']) # 方法一 cmdline.execute('scrapy crawl db'.split(" ")) # 方法二


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3