爬虫课堂(十七)|Scrapy爬虫开发流程

Scrapy爬虫开发流程一般包括如下步骤: 1)确定项目需求。 2)创建Scrapy项目。 3)定义页面提取的Item。 4)分析被爬对象页面。 5)编写爬取网站的Spider并提取Item。 6)编写Item Pipeline来存储提取到的Item(即数据)。 7)运行爬虫。 一、确定项目需求 要爬取简书@IT· 互联网专题(https://www.jianshu.com/c/V2CqjW)下的所有文章,如图17-1所示。

图17-1

该专题中,每页10条数据,总共的页数在10以上,因为它是上拉加载下一页数据,暂时无法得知总页数是多少。假设我们的项目需求就是爬取最近10页的文章信息,包括文章标题,文章URL和文章的作者名称。 二、创建Scrapy项目 在开始爬取之前,必须先创建一个Scrapy项目。 进入存储代码的目录中,在shell中使用scrapy startproject命令运行: scrapy startproject jianshu_spider 其中jianshu_spider为项目名称。 该命令将会创建包含下列内容的jianshu_spider目录:

jianshu_spider/
----scrapy.cfg
----jianshu_spider/
--------__init__.py
--------items.py
--------middlewares.py
--------pipelines.py
--------settings.py
--------spiders/
------------__init__.py

这些文件分别是:

  • scrapy.cfg: 项目的配置文件
  • jianshu_spider/: 该项目的python模块。
  • jianshu_spider/items.py: 项目中的item文件。
  • jianshu_spider/middlewares.py: 项目中的middlewares文件。
  • jianshu_spider/pipelines.py: 项目中的pipelines文件。
  • jianshu_spider/settings.py: 项目的设置文件。
  • jianshu_spider/spiders/: 放置spider代码的目录。

三、定义页面提取的Item Item是保存爬取到的数据的容器,它的使用方法和Python字典类似,并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。 可以通过创建一个 scrapy.Item类,并且定义类型为scrapy.Field的类属性来定义一个Item。 首先根据需要从jianshu.com获取到的数据对Item进行建模。 前面项目需求中得知我们需要获取文章标题,文章URL和文章的作者名称。对此,在Item中定义相应的字段。编辑jianshu_spider目录中的items.py文件:

import scrapy
class JianshuItem(scrapy.Item):
----title = scrapy.Field()
----url = scrapy.Field()
----author_name = scrapy.Field()

四、分析被爬对象页面 编写爬虫程序之前,首先需要对被爬的页面进行分析,主流的浏览器都带有分析页面的工具或插件,比如Chrome浏览器的开发者工具(Tools->Developer->tools)分析页面。 1、数据信息 在Chrome浏览器中打开https://www.jianshu.com/c/V2CqjW,选中第一个文章列表并右击,选择“检查”,查看其HTML代码,如图17-2所示。

图17-2

可以右边红框所示,每篇文章的信息包含在<li>元素中:

<li id="note-25476707" data-note-id="25476707" class="">
...
</li>

文章标题和文章URL在<a class="title"></a>元素中:

<a class="title" target="_blank" href="/p/b74107b6464d">走向架构之路之某个类重载方法很多该如何优化</a>

文章的作者名称在<a class="nickname"></a>元素中:

<a class="nickname" target="_blank" href="/u/f408bdadacce">AWeiLoveAndroid</a>

2、链接信息 上面列出的但是第一页元素的数据,我们要采集它的1-10页的信息,那么就要获取到下一页的链接。有些网站的下一页是通过点击“next”或者“下一页”触发的,简书网站是通过上拉加载。 我们可以点击到在Chrome浏览器的审查页面中选中Network和XHR,再页面上拉加载下一页的文章信息,如图17-3所示。

图17-3

可以发现,在下拉的过程中,XHR下方出现了一个https://www.jianshu.com/c/V2CqjW?order_by=added_at&page=2地址,里面有一个参数为page=2,同时验证发现当page=3时就是第三页的文章信息。 五、编写爬取网站的Spider并提取Item Spider是用户编写用于从单个网站(或者一些网站)爬取数据的类。 其包含了一个用于下载的初始URL,如何跟进网页中的链接以及如何分析页面中的内容, 提取生成item的方法。 创建一个Spider,必须继承scrapy.Spider类, 且定义以下三个属性:

  • name:用于区别Spider。该名字必须是唯一的,不可以为不同的Spider设定相同的名字。
  • start_urls:包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
  • parse()方法。它是spider的一个方法。被调用时,每个初始URL完成下载后生成的Response对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的Request对象。 以下为我们的第一个Spider的伪代码,保存在jianshu_spider/spiders 目录下的jianshu_spider.py文件中:
#-*-coding:utf-8-*-
import scrapy
class JianshuSpider(scrapy.Spider):
# 每一个爬虫的唯一标识
----name="jianshu_spider"
# 定义爬虫爬取的起始点,起始点可以是多个,这里只有一个
----start_urls=[
--------"https://www.jianshu.com/c/V2CqjW"
----]
----def parse(self,response):
# 提取数据信息的代码
......
# 提取链接信息的代码
......

如果上面的代码有上面不明白的,没关系,后面的章节我会详细讲解,现在只需要知道是这么一个大概的流程即可。

从Spider的角度来看,爬取的运行流程如下循环: 1)以初始的URL初始化Request,并设置回调函数。 当该Request下载完毕并返回时,将生成Response,并作为参数传给该回调函数。 2)在回调函数内分析返回的(网页)内容,返回 Item 对象或者 Request 或者一个包括二者的可迭代容器。返回的Request对象之后会经过Scrapy处理,下载相应的内容,并调用设置的callback函数(函数可相同)。 3)在回调函数内,可以使用选择器(Selectors) 来分析网页内容,并根据分析的数据生成Item。 4)最后,由Spider返回的Item将被存到数据库或存入到文件中。 六、编写Item Pipeline来存储提取到的Item(即数据)七、运行爬虫 进入项目的根目录,执行下列命令启动spider: scrapy crawl jianshu_spider crawl jianshu_spider启动用于爬取jianshu.com的spider,将得到类似的输出:

[scrapy] INFO:Scrapy started(bot:tutorial)
[scrapy] INFO:Optional features available:...
[scrapy] INFO:Overridden settings:{}
[scrapy] INFO:Enabledextensions:...
[scrapy] INFO:Enabled downloader middlewares:...
[scrapy] INFO:Enabled spider middlewares:...
[scrapy] INFO:Enabled item pipelines:...
[jianshu_spider] INFO:Spider opened
[jianshu_spider] DEBUG:Crawled(200) <GET https://www.jianshu.com/c/V2CqjW> (referer:None)
[jianshu_spider] DEBUG:Crawled(200)(referer:None)
[jianshu_spider] INFO:Closing spider(finished)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏wOw的Android小站

[Android] Service服务详解以及如何使service服务不被杀死

  服务是一个应用程序组件,可以在后台执行长时间运行的操作,不提供用户界面。一个应用程序组件可以启动一个服务,它将继续在后台运行,即使用户切换到另一个应用程序。...

1.5K1
来自专栏移动开发的那些事儿

Android Sqlite并发问题

如上异常堆栈中的错误信息error code 5: database is locked,经过查找发现code为5代表sqlite中的SQLITE_BUSY异常...

1744
来自专栏指尖下的Android

安卓跨进程通信之Aidl教程详解(一)

进程通信肯定有传输数据和接受并返还数据,先新建两个项目,一个为AidlDemo1作为Service,另一个为AidlDemo2作为Client

3112
来自专栏禹都一只猫博客

python爬虫入门:scrapy爬取书籍的一些信息

1858
来自专栏有困难要上,没有困难创造困难也要上!

Caffe Python开发环境设置

44313
来自专栏Aloys的开发之路

tcpdump捕捉样例

# 下面的例子全是以抓取eth0接口为例,如果不加”-i eth0”是表示抓取所有的接口包括lo。 # 抓取到目标主机example.com的http he...

22410
来自专栏自由而无用的灵魂的碎碎念

解决windows7不能设置壁纸的问题

我的系统是windows server 2008 r2(启用windows 7桌面体验)最近因为系统慢的缘故,强关了一下机,开机进入系统,发现成黑屏了,改变wi...

1274
来自专栏FreeBuf

使用scrapy爬取sebug漏洞库

微信号:freebuf 由于项目需要抓取sebug的漏洞库内容,就利用scrapy框架简单写了个抓取sebug的爬虫,并存入数据库,mysql或mongodb,...

2386
来自专栏七夜安全博客

python爬虫-爬取盗墓笔记

1446
来自专栏V站

python爬虫入门:scrapy爬取书籍的一些信息

Spider类想要表达的是:如何抓取一个确定了的网站的数据。比如在start_urls里定义的去哪个链接抓取,parse()方法中定义的要抓取什么样的数据。 当...

33310

扫码关注云+社区

领取腾讯云代金券