Python网络爬虫技术项目化教程 课件 项目六 引入Scrapy框架 -“构建高效的网络爬虫”_第1页
Python网络爬虫技术项目化教程 课件 项目六 引入Scrapy框架 -“构建高效的网络爬虫”_第2页
Python网络爬虫技术项目化教程 课件 项目六 引入Scrapy框架 -“构建高效的网络爬虫”_第3页
Python网络爬虫技术项目化教程 课件 项目六 引入Scrapy框架 -“构建高效的网络爬虫”_第4页
Python网络爬虫技术项目化教程 课件 项目六 引入Scrapy框架 -“构建高效的网络爬虫”_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

项目6引入Scrapy框架–“构建高效的网络爬虫”任务6.1Scrapy爬虫框架基础6.1.1认识Scrapy框架定义:用Python实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架应用场景:数据挖掘,信息处理或存储历史数据等一系列的程序扩展性:最初为网页抓取设计,也可用于使用API提取数据,或作为通用的网络爬虫灵活性:任何人都可以根据需求方便地修改,提供了多种类型爬虫的基类6.1.2Scrapy框架组件6.1.2Scrapy框架组件1.ScrapyEngine(引擎)角色:框架的"大脑"主要功能:调度请求与响应循环从调度器获取待处理的Request,发送给下载器接收下载器返回的Response,分发给对应的Spider控制组件间通信触发爬虫的启动和关闭流程,管理整个爬取任务的生命周期6.1.2Scrapy框架组件2.Scheduler(调度器)角色:请求的"管理器"主要功能:接收引擎发送的Request请求按照一定方式进行整理排列、入队请求队列管理(FIFO、LIFO或优先级队列)支持请求去重(基于URL和指纹)请求优先级调度,优先处理高优先级请求配合引擎实现"按需请求",控制爬取速度6.1.2Scrapy框架组件3.Downloader(下载器)角色:网络请求的"执行者"主要功能:下载引擎发送的所有Requests请求将获取的Responses交还给引擎与目标网站直接交互的组件网络请求发送(支持GET/POST等方法)处理cookies、代理、认证等高级网络功能响应处理与异常捕获基于异步网络库(如Twisted)实现高并发请求6.1.2Scrapy框架组件4.Spider(爬虫)角色:数据解析的"核心逻辑载体"主要功能:由开发者自定义,处理所有Responses分析提取数据,获取Item字段需要的数据将需要跟进的URL提交给引擎定义起始请求(通过start_requests()方法)解析响应(使用XPath、CSS选择器或正则表达式)生成新请求,实现爬取逻辑的扩展6.1.2Scrapy框架组件5.ItemPipeline(项目管道)角色:数据处理的"流水线"主要功能:对爬虫提取的原始数据进行清洗、验证、存储等后续处理每个项目管道组件都是一个实现了简单方法的Python类数据清洗与转换(去重、清洗无效字段、处理缺失值)数据验证与过滤(根据业务规则验证数据合法性)数据存储(保存到文件或数据库)6.1.2Scrapy框架组件6.Middleware(中间件)角色:请求与响应的"拦截处理器"主要类型:下载器中间件(DownloaderMiddleware)介于Scrapy引擎和下载器之间处理从引擎发送到下载器的请求,以及从下载器返回给引擎的响应设置代理、更换请求头等反爬虫目的常用方法:process_request()、process_response()爬虫中间件(SpiderMiddleware)处理引擎传回的Response对象和Spiders生成的items和requests主要作用:在Response发送给Spider之前对Response进行处理在Request发送给Scheduler之前对Request进行处理在Item发送给ItemPipeline之前对Item进行处理任务6.2Scrapy安装6.2.1安装Scrapy安装方式:通过Python的包管理器pip完成安装操作步骤:按下Win+R组合键,输入cmd并按回车键,打开命令提示符窗口输入安装命令:pipinstallscrapy等待安装完成,自动安装Scrapy及其相关依赖6.2.2验证安装导入验证:importscrapy版本查看:scrapy.version_info预期结果:成功导入Scrapy库,显示版本信息命令验证:在命令行中输入scrapy,查看可用命令列表预期结果:显示Scrapy的常见命令列表6.2.2验证安装全局命令:在任何位置都可以执行项目命令:在项目环境内运行命令含义startproject创建爬虫项目genspider用于生成爬虫crawl启动Spider爬虫check检查代码list列出所有可用的爬虫fetch将网页内容下载下来,然后在终端打印当前返回的内容version查看版本信息runspider运行Spidersettings系统设置信息bench测试电脑当前爬取速度性能shell打开Scrapy显示台任务6.3认识Scrapy框架中的对象6.3.1Request对象Request对象:描述HTTP请求,包含URL、回调函数、请求头等构造函数参数列表:Request(url[,callback,method='GET',headers,body,cookies,meta,encoding='utf-8',priority=0,dont_filter=False,errback])Request对象特点:由Spider产生,由Downloader执行支持GET、POST等多种HTTP方法可以携带自定义头部信息支持Cookie管理支持优先级调度可以通过meta参数传递额外数据6.3.2Response对象Response对象:描述HTTP响应,包含状态码、响应体、请求信息等构造函数参数列表:Response(url[,status=200,headers=None,body=b'',flags=None,request=None])Response对象特点:由Downloader生成,由Spider处理Response对象类型:Response:基类TextResponse:Response的子类,支持新的构造参数HtmlResponse:TextResponse的子类,用于HTML文档XmlResponse:TextResponse的子类,用于XML文档6.3.2Response对象Response常用方法:1.CSS选择器response.selector.css()#完整形式response.css()#简写形式2.XPath选择器response.selector.xpath()#完整形式response.xpath()

#简写形式以上两种方式的返回值都是SelectorList的实例对象,对此实例对象调用get()或.getall()方法,分别获得第一个符合条件的元素,和所有符合条件的元素的list。6.3.3Item对象Item对象:一种简单的容器,用于保存爬取得到的数据Item对象作用:提供固定结构,避免字典的拼写错误和数据不一致问题Item对象特点:由Spider生成,由ItemPipeline处理提供跟字典相似的API方便的语法声明可用字段提供了保护机制避免未定义字段错误6.3.3Item对象定义Item类:importscrapyclassProduct(scrapy.Item):name=scrapy.Field()price=scrapy.Field()stock=scrapy.Field()last_updated=scrapy.Field(serializer=str)Field对象:定义了每个字段的元数据(metadata)可以为每个字段指明任何类型的元数据Field类就是Python中dict类的别名携带的元数据能够指导Scrapy的pipeline工具类对数据进行处理6.3.3Item对象Item使用示例:importscrapyclassProduct(scrapy.Item):name=scrapy.Field()price=scrapy.Field()stock=scrapy.Field()#创建Product实例product=Product(name='pc',price=1500)print(product)#输出:{'name':'pc','price':1500}#访问字段值print(product['name'])#输出:'pc'print(product['price'])#输出:1500#查看所有键print(product.keys())#输出:dict_keys(['name','price'])#查看所有键值对print(product.items())#输出:ItemsView([('name','pc'),('price',1500)])任务6.4创建第一个Scrapy项目1.项目创建命令基本语法:scrapystartproject项目名称示例:scrapystartprojectmySpider执行位置:在自定义的项目目录中执行(如Windows系统下的"D:\PythonProject"目录)执行结果:系统显示mySpider项目的完整目录结构2.Scrapy主要文件及其作用scrapy.cfg项目根目录文件项目配置文件,存储部署相关配置。mySpider/项目模块目录项目的核心Python模块,包含所有爬虫逻辑、配置和组件定义。items.py目标文件定义数据载体Item类,用于结构化存储爬取的数据。middlewares.py中间件文件定义下载中间件和蜘蛛中间件的逻辑,实现请求/响应的拦截与处理。pipelines.py管道文件定义数据管道逻辑,对蜘蛛输出的Item进行清洗、验证、存储等处理。settings.py设置文件控制Scrapy框架的行为,包含默认配置和自定义配置,支持通过环境变量或代码动态修改。spiders/存储爬虫代码目录存储所有自定义蜘蛛(Spider)代码,每个蜘蛛对应一个爬取任务。3.使用scrapy访问测试网站步骤1:创建测试网站(使用flask)#安装flaskpipinstallflask#创建flask应用步骤2:运行测试网站运行flask应用打开浏览器访问::5000/查看网站效果3.使用scrapy访问测试网站步骤3:创建Scrapy项目#创建项目文件夹mkdirproject4cdproject4#创建Scrapy项目scrapystartprojectdemo步骤4:创建Spider文件打开project4文件夹,在spider中创建文件myspider。步骤4:创建Spider文件在myspider.py中写入代码:步骤5:创建运行脚本在demo文件夹中创建run.py,写入代码步骤6:运行爬虫并查看结果#运行爬虫pythonrun.py任务6.5使用Scrapy爬取豆瓣图书Top2506.5.1项目创建与结构搭建创建项目命令:scrapystartprojectdoubanTop项目结构生成:6.5.2定义Item#items.py-定义爬取豆瓣图书Top250信息的数据结构importscrapyclassDoubantopItem(scrapy.Item):title=scrapy.Field()#书名

author=scrapy.Field()#作者

press=scrapy.Field()#出版社

description=scrapy.Field()#图书描述

start_year=scrapy.Field()#出版年份

page=scrapy.Field()#页数

price=scrapy.Field()#价格

binding=scrapy.Field()#装帧类型

ISBN=scrapy.Field()#ISBN编号

series=scrapy.Field()#丛书信息

score=scrapy.Field()#评分

producers=scrapy.Field()#出品方

translator=scrapy.Field()#译者

subtitle=scrapy.Field()#副标题

original_name=scrapy.Field()#原作名生成爬虫命令:cddoubanTop#进入项目路径scrapygenspiderdouban#在子目录中创建爬虫文件项目结构生成:生成文件spiders/douban.py6.5.3编写Spider代码#spiders/douban.pyimportscrapyimportrefromdoubanTop.itemsimportDoubantopItem#把items.py里面的名字对应地引进来classDoubanSpider(scrapy.Spider):name='douban'#allowed_domains=['']start_urls=[]def__init__(self):forpageinrange(0,226,25):self.urls='/top250?start={0}'self.start_urls.append(self.urls.format(page))defparse(self,response):table_list=response.xpath('//div[@class="indent"]/table')fortableintable_list:urls=table.xpath('.//div[@class="pl2"]/a/@href').extract_first()print(urls)yieldscrapy.Request(url=urls,callback=self.detail_parse)6.5.3编写Spider代码defdetail_parse(self,response):item=DoubantopItem()content=response.text.encode('gbk','ignore').decode('gbk')series=pile(r'<spanclass="pl">丛书:</span> <ahref=".*?">(.*?)</a><br>')press=pile(r'<spanclass="pl">出版社:</span>\s*<ahref=".*?">(.*?)</a>')producers=pile(r'<spanclass="pl">出品方:</span>\s*<ahref=".*?">(.*?)</a>')translator=pile(r'<spanclass="pl">译者:</span>\s*<aclass=""href=".*?">(.*?)</a>')title=re.findall('<metaproperty="og:title"content="(.*?)"/>',content)item['title']=title[0]iftitleelseNoneauthor=re.findall('<metaproperty="book:author"content="(.*?)"/>',content)item['author']=author[0]ifauthorelseNonedescription=re.findall('<metaproperty="og:description"content="(.*?)\.\.\."/>',content,re.S)item['description']=description[0].replace('\n','')ifdescriptionelseNonestart_year=re.findall('<spanclass="pl">出版年:</span>(.*?)<br/>',content)item['start_year']=start_year[0].strip()ifstart_yearelseNonepage=re.findall('<spanclass="pl">页数:</span>(.*?)<br/>',content)item['page']=page[0]ifpageelseNoneprice=re.findall('<spanclass="pl">定价:</span>(.*?)<br/>',content)item['price']=price[0]ifpageelseNonebinding=re.findall('<spanclass="pl">装帧:</span>(.*?)<br/>',content)item['binding']=binding[0]ifbindingelseNoneISBN=re.findall('<spanclass="pl">ISBN:</span>(.*?)<br/>',content)item['ISBN']=ISBN[0]ifISBNelseNonepress=re.findall(press,content)item['press']=press[0]ifpresselseNoneseries=re.findall(series,content)item['series']=series[0]ifserieselseNonescore=re.findall('<strongclass="llrating_num"property="v:average">(.*?)</strong>',content)item['score']=score[0]ifscoreelseNoneproducers=re.findall(producers,content)item['producers']=producers[0]ifproducerselseNonetranslator=re.findall(translator,content)item['translator']=translator[0]iftranslatorelseNonesubtitle=re.findall('<spanclass="pl">副标题:</span>(.*?)<br/>',content)item['subtitle']=subtitle[0]ifsubtitleelseNoneoriginal_name=re.findall('<spanclass="pl">原作名:</span>(.*?)<br/>',content)item['original_name']=original_name[0]iforiginal_nameelseNoneyielditem6.5.3编写Spider代码#pipelines.py-数据存储管道importcsvclassDoubantopPipeline(object):def__init__(self):path='douban_book_Top250.csv'self.file=open(path,'a+',encoding='utf-8')self.writer=csv.writer(self.file)defprocess_item(self,item,spider):self.writer.writerow((item['title'],item['author'],item['press'],item['description'],item['start_year'],item['page'],item['price'],item['binding'],item['ISBN'],item['series'],item['score'],item['producers'],item['translator'],item['subtitle'],item['original_name']))returnitemdefclose_spider(self,spider):self.file.close()6.5.4修改pipeline.py文件1.基本配置:BOT_NAME:爬虫名称SPIDER_MODULES:爬虫模块路径ROBOTSTXT_OBEY=False:不遵守robots.txt规则2.请求控制:DOWNLOAD_DELAY=3:设置3秒下载延迟,避免被封DEFAULT_REQUEST_HEADERS:设置了User-Agent伪装成Chrome浏览器3.管道配置:ITEM_PIPELINES:启用了自定义的DoubantopPipelineFEED_EXPORT_ENCODING="utf-8":确保输出文件使用UTF-8编码4.其他重要设置:并发请求、中间件、扩展等保持默认值;禁用了cookies和telnet控制台6.5.5修改settings.py文件运行命令:scrapycrawlDouban项目结构生成:生成douban_book_Top250.csv文件6.5.6运行Scrapy爬虫6.5.7查看爬虫结果项目实战Scrapy爬取当当网站图书数据【任务描述】本任务基于Scrapy框架开发爬虫程序,实现对当当网图书搜索结果的自动化数据采集与结构化存储。通过分析网页结构、设计反爬策略及搭建数据存储管道,完成指定关键词图书信息的爬取、清洗与持久化,为后续数据分析提供基础数据源。【任务实施】1.项目创建与结构搭建创建Scrapy项目:scrapystartprojectdangdang项目结构:【任务实施】2.定义数据字段(items.py)importscrapyclassBookItem(scrapy.Item):ID=scrapy.Field()#编号

bTitle=scrapy.Field()#图书名称

bAuthor=scrapy.Field()#作者

bPublisher=scrapy.Field()#出版社

bDate=scrapy.Field()#出版日期

bPrice=scrapy.Field()#价格

bDetail=scrapy.Field()#内容简介

bImage=scrapy.Field()#封面图片【任务实施】3.图书信息采集页面分析与URL规律提取搜索URL分析:初始搜索:/?key=Python&act=input参数说明:key为搜索关键词,act=input标识输入框查询分页URL规律:第二页:/?key=Python&page_index=2规律:通过page_index参数控制页码,从1开始递增页面结构分析:图书信息集中在<liclass="line"ddt-pit="xxx">标签内使用XPath定位关键元素【任务实施】3.图书信息采集爬虫开发与数据提取importscrapyfromdangdang.itemsimportBookItemclassMySpider(scrapy.Spider):#关键变量与配置

name="mySpider"#爬虫名称,用于命令行启动

key='python'#搜索关键词

source_url='/'#搜索页面基础URL#请求生成与初始爬取

defstart_requests(self):self.count=0#初始化计数器,用于生成唯一IDurl=MySpider.source_url+"?key="+MySpider.key#构造搜索URLyieldscrapy.Request(url=url,callback=self.parse)#发起请求并指定解析函数

#文件扩展名处理

defgetFileExt(self,url):p=url.rindex(".")#查找最后一个点号位置

ifp>=0:s=url[p:]#截取扩展名部分

ifs[len(s)-1]=="/":#处理可能的斜杠

s=s[0:len(s)-1]else:s=""returns【任务实施】#页面解析与数据提取

defparse(self,response):try:#处理页面编码,使用gbk解码

selector=scrapy.Selector(text=response.body.decode("gbk"))#定位所有图书项(li标签)

lis=selector.xpath("//li['@ddt-pit'][starts-with(@class,'line')]")forliinlis:self.count+=1#计数器递增

ID="%06d"%self.count#生成6位数字ID#使用XPath提取各字段信息

bTitle=li.xpath("./a[position()=1]/@title").extract_first()bPrice=li.xpath("./p[@class='price']/span[@class='search_now_price']/text()").extract_first()bAuthor=li.xpath("./p[@class='search_book_author']/span[position()=1]/a/@title").extract_first()bDate=li.xpath("./p[@class='search_book_author']/span[position()=last()-1]/text()").extract_first()bPublisher=li.xpath("./p[@class='search_book_author']/span[position()=last()]/a/@title").extract_first()bDetail=li.xpath("./p[@class='detail']/text()").extract_first()#处理图片URLurl=li.xpath("./a[@name='itemlist-picture']/img/@data-original").extract_first()ifnoturl:url=li.xpath("./a[@name='itemlist-picture']/img/@src").extract_first()ifurl:#下载图像

bImage=ID+self.getFileExt(url)url=response.urljoin(url)#转换为绝对URLrequest=scrapy.Request(url=url,callback=self.download)request.meta["bImage"]=bImage#传递文件名到回调函数

yieldrequestelse:bImage=""#处理可能的None值,转换为空字符串

item=BookItem()item["ID"]=IDitem["bTitle"]=bTitle.strip()ifbTitleelse""item["bAuthor"]=bAuthor.strip()ifbAuthorelse""item["bDate"]=bDate.strip()[1:]ifbDateelse""item["bPublisher"]=bPublisher.strip()ifbPublisherelse""item["bPrice"]=bPrice.strip()ifbPriceelse""item["bDetail"]=bDetail.strip()ifbDetailelse""item["bImage"]=bImageyielditem#处理翻页逻辑,最后一页时,link为Nonelink=selector.xpath("//div[@class='paging']/ul[@name='Fy']/li[@class='next']/a/@href").extract_first()iflink:url=response.urljoin(link)yieldscrapy.Request(url=url,callback=self.parse)exceptExceptionaserr:print(err)#简单错误处理【任务实施】#图片下载处理

defdownload(self,response):bImage=response.meta["bImage"]try:f=open("download\\"+bImage,"wb")#以二进制写入模式打开文件

f.write(response.body)f.close()print("downloaded",bImage)except:print("downloading",bImage,"failed")【任务实施】3.图书信息采集反爬策略配置#settings.py-关键反爬配置#伪装浏览器请求DEFAULT_REQUEST_HEADERS={'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language':'zh-CN,zh;q=0.9','User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.124Safari/537.36'}#设置下载延迟(2秒)DOWNLOAD_DELAY=2#不遵守robots.txt(注意合规性)ROBOTSTXT_OBEY=False#启用自定义管道ITEM_PIPELINES={"dangdang.pipelines.BookPipeline":300,}【任务实施】4.数据存储方案创建数据库与表结构importsqlite3importosclassBookPipeline(object):defopen_spider(self,spider):print("open_spider")self.con=sqlite3.connect("books.db")self.cursor=self.con.cursor()try:self.cursor.execute("droptablebooks")except:passsql="createtablebooks(IDvarchar(8)primarykey,bTitlevarchar(256),bAuthorvarchar(256),bPublishervarchar(256),bDatevarchar(256),

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论