pythonのscrapy抓取网站数据

news/2024/5/15 1:06:28/文章来源:https://blog.csdn.net/weixin_30670965/article/details/97743207

(1)安装Scrapy环境

  步骤请参考:https://blog.csdn.net/c406495762/article/details/60156205

  需要注意的是,安装的时候需要根据自己的python的版本进行安装。

(2)创建Scrapy项目

  通过命令创建:

scrapy startproject tutorial

  在任意文件夹运行都可以,如果提示权限问题,可以加sudo运行。这个命令将会创建一个名字为tutorial的文件夹,文件夹结构如下:

|____scrapy.cfg     # Scrapy部署时的配置文件
|____tutorial         # 项目的模块,引入的时候需要从这里引入
| |______init__.py    
| |______pycache__
| |____items.py     # Items的定义,定义爬取的数据结构
| |____middlewares.py   # Middlewares的定义,定义爬取时的中间件
| |____pipelines.py       # Pipelines的定义,定义数据管道
| |____settings.py       # 配置文件
| |____spiders         # 放置Spiders的文件夹
| | |______init__.py
| | |______pycache__

  Spider是由你来定义的Class,Scrapy用它来从网页里抓取内容,并将抓取的结果解析。不过这个Class必须要继承Scrapy提供的Spider类scrapy.Spider,并且你还要定义Spider的名称和起始请求以及怎样处理爬取后的结果的方法。

创建一个Spider也可以用命令生成,比如要生成Quotes这个Spider,可以执行命令。

scrapy genspider 爬虫名称 "作用域(eg:baidu.com)"

  首先进入到刚才创建的tutorial文件夹,然后执行genspider这个命令,第一个参数是Spider的名称,第二个参数是网站域名。执行完毕之后,你会发现在spiders文件夹中多了一个quotes.py,这就是你刚刚创建的Spider,内容如下:

# -*- coding: utf-8 -*-
import scrapyclass QuotesSpider(scrapy.Spider):name = "quotes"allowed_domains = ["quotes.toscrape.com"]start_urls = ['http://quotes.toscrape.com/']def parse(self, response):pass

  可以看到有三个属性,name,allowed_domains,start_urls,另外还有一个方法parse

    name,每个项目里名字是唯一的,用来区分不同的Spider。

    allowed_domains允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,就会被过滤掉。

    start_urls,包含了Spider在启动时爬取的url列表,初始请求是由它来定义的。

    parse,是Spider的一个方法,默认情况下,被调用时start_urls里面的链接构成的请求完成下载后,返回的response就会作为唯一的参数传递给这个函数,该方法负责解析返回的response,提取数据或者进一步生成要处理的请求。

创建Item
  Item是保存爬取数据的容器,它的使用方法和字典类似,虽然你可以用字典来表示,不过Item相比字典多了额外的保护机制,可以避免拼写错误或者为定义字段错误。

  创建Item需要继承scrapy.Item类,并且定义类型为scrapy.Field的类属性来定义一个Item。观察目标网站,我们可以获取到到内容有text, author, tags

  所以可以定义如下的Item,修改items.py如下:

# -*- coding: utf-8 -*-# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.htmlimport scrapyclass QuoteItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field() '''item 时报错爬取数据的容器,它的使用方法和字典类似,虽然你可以用字典来表示,不过Item相比字典多了额外的保护机制,可以避免拼写错误或者未定义字段错误。创建item需要继承Scrapy.Item类,并且定义类型为scrapy.Field的类属性来定义一个Item。观察目标网站,我们可以获取到内容有text、author、tags'''text = scrapy.Field()author = scrapy.Field()tags = scrapy.Field()

  定义了三个Field,接下来爬取时我们会使用它。

解析Response
  在上文中说明了parse方法的参数resposne是start_urls里面的链接爬取后的结果。所以在parse方法中,我们可以直接对response包含的内容进行解析,比如看看请求结果的网页源代码,或者进一步分析源代码里面包含什么,或者找出结果中的链接进一步得到下一个请求。

  观察网站,我们可以看到网页中既有我们想要的结果,又有下一页的链接,所以两部分我们都要进行处理。

  首先看一下网页结构,每一页都有多个class为quote的区块,每个区块内都包含text,author,tags,所以第一部需要找出所有的quote,然后对每一个quote进一步提取其中的内容。

  提取的方式可以选用CSS选择器或XPath选择器,在这里我们使用CSS选择器进行选择,parse方法改写如下:

def parse(self, response):quotes = response.css('.quote')for quote in quotes:text = quote.css('.text::text').extract_first()author = quote.css('.author::text').extract_first()tags = quote.css('.tags .tag::text').extract()

  在这里使用了CSS选择器的语法,首先利用选择器选取所有的quote赋值为quotes变量。
  然后利用for循环对每个quote遍历,解析每个quote的内容。

  对text来说,观察到它的class为text,所以可以用.text来选取,这个结果实际上是整个带有标签的元素,要获取它的内容,可以加::text来得到。这时的结果是大小为1的数组,所以还需要用extract_first方法来获取第一个元素,而对于tags来说,由于我们要获取所有的标签,所以用extract方法获取即可。

<div class="quote" itemscope="" itemtype="http://schema.org/CreativeWork"><span class="text" itemprop="text">“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”</span><span>by <small class="author" itemprop="author">Albert Einstein</small><a href="/author/Albert-Einstein">(about)</a></span><div class="tags">Tags:<meta class="keywords" itemprop="keywords" content="change,deep-thoughts,thinking,world"> <a class="tag" href="/tag/change/page/1/">change</a><a class="tag" href="/tag/deep-thoughts/page/1/">deep-thoughts</a><a class="tag" href="/tag/thinking/page/1/">thinking</a><a class="tag" href="/tag/world/page/1/">world</a></div></div>

使用Item
  刚才定义了Item,接下来就要轮到使用它了,你可以把它理解为一个字典,不过在声明的时候需要实例化。然后依次对刚才解析的结果赋值,返回即可。

  接下来QuotesSpider改写如下:

# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import QuoteItemclass QuotesSpider(scrapy.Spider):# 爬虫名称name = 'quotes'# 允许爬虫爬取的域名,如果初始或者后续请求链接不是这个域名下,就会被过滤allowed_domains = ['quotes.toscrape.com']# 包含了Spider在启动时爬取的url列表,初始请求是由它来定义的start_urls = ['http://quotes.toscrape.com/']# 时Spider的一个方法,默认情况下,被调用时start_urls里面的# 链接构成的请求完成下载后,返回的response就会被作为唯一的# 参数传递给这个函数,该方法负责解析返回的response,提取数# 据或者进一步生成要处理的请求def parse(self, response):quotes = response.css(".quote")for quote in quotes:item = QuoteItem()item['text'] = quote.css(".text::text").extract_first()item['author'] = quote.css(".author::text").extract_first()item['tags'] = quote.css(".tags .tag::text").extract()yield itemnext = response.css('.page .next a::attr("href")').extract_first()url = response.urljoin(next)yield scrapy.Request(url = url,callback = self.parse)

  如此一来,首页的所有内容就解析出来了,并赋值成了一个个QuoteItem。

后续Request
  如上的操作实现了从初始页面抓取内容,不过下一页的内容怎样继续抓取?这就需要我们从该页面中找到信息来生成下一个请求,然后下一个请求的页面里找到信息再构造下一个请求,这样循环往复迭代,从而实现整站的爬取。

 

  观察到刚才的页面拉到最下方,有一个Next按钮,查看一下源代码,可以发现它的链接是/page/2/,实际上全链接就是http://quotes.toscrape.com/page/2,通过这个链接我们就可以构造下一个请求。

  构造请求时需要用到scrapy.Request,在这里我们传递两个参数,url和callback。

url,请求链接

callback,回调函数,当这个请求完成之后,获取到response,会将response作为参数传递给这个回调函数,回调函数进行解析或生成下一个请求,如上文的parse方法。

在这里,由于parse就是用来解析text,author,tags的方法,而下一页的结构和刚才已经解析的页面结构是一样的,所以我们还可以再次使用parse方法来做页面解析。

好,接下来我们要做的就是利用选择器得到下一页链接并生成请求,在parse方法后追加下面的代码。

next = response.css('.pager .next a::attr(href)').extract_first()
url = response.urljoin(next)
yield scrapy.Request(url=url, callback=self.parse)

  第一句代码是通过CSS选择器获取下一个页面的链接,需要获取<a>超链接中的href属性,在这里用到了::attr(href)操作,通过::attr加属性名称我们可以获取属性的值。然后再调用extract_first方法获取内容。

  第二句是调用了urljoin方法,它可以将相对url构造成一个绝对的url,例如获取到的下一页的地址是/page/2,通过urljoin方法处理后得到的结果就是http://quotes.toscrape.com/page/2/

  第三句是通过url和callback构造了一个新的请求,回调函数callback依然使用的parse方法。这样在完成这个请求后,response会重新经过parse方法处理,处理之后,得到第二页的解析结果,然后生成第二页的下一页,也就是第三页的请求。这样就进入了一个循环,直到最后一页。

  通过几行代码,我们就轻松地实现了一个抓取循环,将每个页面的结果抓取下来了。

  现在改写之后整个Spider类是这样的:

# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import QuoteItemclass QuotesSpider(scrapy.Spider):# 爬虫名称name = 'quotes'# 允许爬虫爬取的域名,如果初始或者后续请求链接不是这个域名下,就会被过滤allowed_domains = ['quotes.toscrape.com']# 包含了Spider在启动时爬取的url列表,初始请求是由它来定义的start_urls = ['http://quotes.toscrape.com/']# 时Spider的一个方法,默认情况下,被调用时start_urls里面的# 链接构成的请求完成下载后,返回的response就会被作为唯一的# 参数传递给这个函数,该方法负责解析返回的response,提取数# 据或者进一步生成要处理的请求def parse(self, response):quotes = response.css(".quote")for quote in quotes:item = QuoteItem()item['text'] = quote.css(".text::text").extract_first()item['author'] = quote.css(".author::text").extract_first()item['tags'] = quote.css(".tags .tag::text").extract()yield itemnext = response.css('.page .next a::attr("href")').extract_first()url = response.urljoin(next)yield scrapy.Request(url = url,callback = self.parse)

  接下来让我们试着运行一下看看结果,进入目录,运行如下命令:

scrapy crawl quotes

  正常情况下这里就会得到如图效果(部分):

  但是也有可能会遇到这种情况:

  再回过头看看我们上边输出的正确结果,这个时候的解决办法是通过提示报错的地址找到manhole.py,然后将该文件中的所有async改为其它的名字比如async1,即可解决相应的问题。

  首先Scrapy输出了当前的版本号,启动的项目。其次输出了当前在settings.py中的一些重写后的配置。然后输出了当前所应用的middlewares和pipelines,middlewares是默认启用的,如果要修改,我们可以在settings.py中修改,pipelines默认是空,同样也可以在settings.py中配置,后面会进行讲解。

  再接下来就是输出各个页面的抓取结果了,可以看到它一边解析,一边翻页,直至将所有内容抓取完毕,然后终止。

  在最后Scrapy输出了整个抓取过程的统计信息,如请求的字节数,请求次数,响应次数,完成原因等等。

  这样整个Scrapy程序就成功运行完毕了。

  可以发现我们通过非常简单的一些代码就完成了一个网站内容的爬取,相比之前自己一点点写程序是不是简洁太多了?

保存到文件
  刚才运行完Scrapy后,我们只在控制台看到了输出结果,如果想将结果保存该怎么办呢?

  比如最简单的形式,将结果保存成Json文件。

  要完成这个其实不需要你写任何额外的代码,Scrapy提供了Feed Exports可以轻松地将抓取结果输出,例如我们想将上面的结果保存成Json文件,可以执行如下命令:

scrapy crawl quotes -o quotes.json

  运行后发现项目内就会多了一个quotes.json文件,里面包含的就是刚才抓取的所有内容,是一个Json格式,多个项目由中括号包围,是一个合法的Json格式。

  另外你还可以每一个Item一个Json,最后的结果没有中括号包围,一行对应一个Item,命令如下:

scrapy crawl quotes -o quotes.jl

  或者

scrapy crawl quotes -o quotes.jsonlines

  另外还支持很多格式输出,例如csv,xml,pickle,marshal等等,还支持ftp,s3等远程输出,另外还可以通过自定义ItemExporter来实现其他的输出。

  例如如下命令分别对应输出为csv,xml,pickle,marshal,格式以及ftp远程输出:

scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv

其中ftp输出需要你正确配置好你的用户名,密码,地址,输出路径,否则会报错。

通过Scrapy提供的Feed Exports我们可以轻松地输出抓取结果到文件,对于一些小型项目这应该是足够了,不过如果想要更复杂的输出,如输出到数据库等等,你可以使用Item Pileline更方便地实现。

 

转载于:https://www.cnblogs.com/pengpengzhang/p/9475253.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_765300.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建前后端分离网站

后台网站基于&#xff1a;VueCli 3.0 ElementUI Asp.Net Core WebApi MongoDB 实现 前端&#xff1a;VueCli 3.0 安装Node.JS&#xff0c;npm 是 JavaScript 世界的包管理工具,并且是 Node.js 平台的默认包管理工具。下载Node.JS 安装 Vue Cli 3.0 npm install -g vue/cli…

HTML吸引人眼球的网页,超吸引眼球的优秀网站设计欣赏

1. Catch Fish And ChipsCatch fish and chips 是一家专卖炸鱼块及薯片的连锁餐厅&#xff0c;网站已分段的影片衔接各页面之间的转换&#xff0c;清晰的画面不仅凸显食材的新鲜、美味的形象&#xff0c;也巧妙的抓住了消费者的注意力&#xff0c;会让人想认真转动滚轮到最下方…

java 网站加入git_使用git提交项目到码云

一、git安装2、找到Git-2.11.exe文件&#xff0c;双击安装3、点击next继续下一步4、更改安装路径&#xff0c;点击next下一步5、勾选Additonai icons&#xff0c;创建桌面图标&#xff0c;不想创建桌面图标可不勾选此项&#xff0c;点击next下一步6、在Adjusting your PATH env…

如何判断一个网站是不是php,怎样查看一个网站是否使用织梦程序做的及其版本...

原标题&#xff1a;怎样查看一个网站是否使用织梦程序做的及其版本对于一个自己看上的好网站&#xff0c;我们总是迫不及待的想知道它是用什么程序做的。然后自己也可以通过仿站、采集等做一个类似的站点。今天分享点如何判断一个网站是否是使用的织梦DedeCMS程序制作的知识&am…

Linux三大主流网站构建平台,第二十三期 Linux的LAMP网站平台构建

在CentOS7系统中开启Web/FTP等网络服务应用时&#xff0c;可能会收到默认配置的防火墙、SELinux等安全防护策略影响。为了避免干扰&#xff0c;学习过程中建议禁止这些保护机制。关闭防火墙策略&#xff1a;[rootsvr7 ~]# systemctl stop firewalld[rootsvr7 ~]# systemctl dis…

不错的anroid源码在线浏览网站【学习笔记】

不错的anroid源码在线浏览网站&#xff1a;http://androidxref.com/ 转载于:https://www.cnblogs.com/zzb-Dream-90Time/p/10643972.html

网站截流项目长期正规可落地操作3天日赚400+

在大多数人的印象里网站赚钱对于小白来说难度较高&#xff0c;而且周期比较长&#xff0c;需要每天更新文章和做SEO坚持几个月下来也未必能带来多大的收益&#xff0c;而很多人在坚持1个月不到就放弃了。 网站截流&#xff0c;顾名思义就是截取别人的流量来操作变现&#xff0…

蜘蛛池对网站收录和排名的促进作用究竟有多大?

很多人都认为使用蜘蛛池可以促进网站的收录和排名&#xff0c;但是&#xff0c;因为大部分人购买蜘蛛池不懂辨别&#xff0c;导致&#xff0c;买了蜘蛛池也没有效果&#xff0c;那么&#xff0c;蜘蛛池对网站收录和排名的促进作用究竟有多大呢&#xff1f; 一、什么是蜘蛛池&am…

为什么SEO越来越难做了?SEO怎么才能做出效果?

SEO越来越难做&#xff0c;这已经成为一种常态&#xff0c;不像以前做SEO可以坐享其成&#xff0c;现在做SEO的难度要比以前大很多&#xff0c;那么&#xff0c;为什么SEO越来越难做了&#xff1f;SEO怎么才能做出效果&#xff1f; 一、竞争激烈 以前SEO好做的时候&#xff0c…

网站关键词的SEO技巧,快速获得百度排名首页

网站SEO优化的核心任务&#xff0c;就是快速获得网站关键词在百度首页的排名&#xff0c;这也是每个网站运营人员的期望所在。然而&#xff0c;由于大多数新手的操作总是事与愿违&#xff0c;无论如何努力&#xff0c;都没有使用正确的SEO技巧把排名做好&#xff01; 其实&…

做SEO和SEM有什么区别?哪个推广效果会更好?

很多企业在选择营销方式上&#xff0c;存在错误的认知&#xff0c;不知道怎么选择&#xff0c;是免费的SEO还是付费的SEM&#xff1f;究其原因&#xff0c;是不知道SEO和SEM有什么区别&#xff0c;企业做推广用哪种方式&#xff0c;推广效果会更好一些呢&#xff1f; 一、SEO和…

网站文章关键词重复,对于SEO有哪些不良影响?

新手写文章&#xff0c;一般都习惯逮着一个关键词往死里写&#xff0c;各种长尾&#xff0c;但是&#xff0c;在搜索的时候会发现&#xff0c;关键词重复率太高&#xff0c;那么&#xff0c;网站文章关键词重复&#xff0c;对于SEO有哪些不良影响呢&#xff1f; 一、什么是关键…

反链是什么意思?网站反链对于SEO有哪些作用?

大家在做网站SEO的时候&#xff0c;会接触一个词汇&#xff0c;叫做反链&#xff0c;或者是反向链接&#xff0c;而且&#xff0c;在使用站长工具查询的时候&#xff0c;会看到反链数据&#xff0c;那么&#xff0c;反链是什么意思&#xff1f;网站反链对于SEO有哪些作用呢&…

内页收录慢怎么办?网站内页多久能被百度收录?

很多网站上线以后&#xff0c;首页收录在一周内就可以完成&#xff0c;在百度搜索品牌词就会在首页显示&#xff0c;排名比较稳&#xff0c;但是&#xff0c;文章页却很容易一直不被收录&#xff0c;那么&#xff0c;内页收录慢怎么办&#xff1f;网站内页多久能被百度收录呢&a…

SEO行业怎么了?

SEO行业最近很焦虑&#xff0c;打开交流群都是流量排名掉了、网站出问题、SEO还有前景吗诸如此类的话题。我也是焦虑大军的其中一员&#xff0c;以自己狭隘的角度思考的发际线都前移了&#xff0c;总结一些自己对于SEO行业的思考&#xff0c;仅代表个人观点。 一.原创还是不原…

知名在线音乐网站音悦Tai疑似倒闭

知名在线音乐网站音悦Tai疑似倒闭&#xff0c;官网无法正常访问&#xff0c;App数据异常被下架&#xff0c;官方微博账号也改行卖鞋&#xff0c;估计凉了! 音悦台上线于2009年&#xff0c;建站之初凭借&#xff1a;更新快&#xff0c;画质高&#xff0c;韩流正盛&#xff0c;迅…

实战分享:如何通过黑帽SEO快速获取庆余年这类电视剧流量

不少人都唱衰SEO这个行业&#xff0c;实际上大多数都是SEO工薪阶层在谈论这个话题&#xff0c;当然不可否认搜索引擎优化确实没有以前那么火热&#xff0c;但是不代表SEO就没有前途了。我最近做了一个SEO站&#xff0c;主要是用来攻克黑帽操作&#xff0c;目的就是快速做流量。…

正式发布!微信小程序seo搜索优化指南!

继上次发布小程序页面搜索指导之后&#xff0c;微信新发布小程序seo搜索优化指南&#xff0c;推出新的小程序搜索标准 微信发布小程序seo搜索优化指南 小程序 微信 微新闻 第1张 以下是微信官方发布的具体搜索标准&#xff1a; 小程序里跳转的页面 (url) 可被直接打开。 小程…

谷歌搜索突显网站的ICO图标和网址

在继谷歌搜索移动端实行优先展示网站图标和网址之后。PC端搜索结果也开始调整&#xff0c;突出显示网站图标和网址! 此前谷歌搜索结果突出显示图标和网址一直是在移动端实行&#xff0c;近日pc端终于跟上&#xff0c;在谷歌搜索网站品牌词时会将网站的图标和网址进行突出显示&a…

网站降权了怎么办?如何快速恢复

流量&#xff0c;排名是一个网站的命脉&#xff0c;网站降权了怎么办&#xff0c;如何快速恢复&#xff0c;盲目的操作可能导致雪上加霜。今天这篇文章&#xff0c;充分的带你了解网站降权恢复的必要知识&#xff0c;少做无用功&#xff0c;快速解决问题。 一、站点是否是真的…