Scrapy-Spider爬取过程、实例开发和代码分析(二))

阿里云双11来了!从本博客参与阿里云,服务器最低只要86元/年!

在上一篇文章中,我们简述了Scrapy的工作原理和流程,是时候完成一个简单的项目了。

流程综述

该项目的目的是爬取某度网站的新闻页的热点新闻里的标题数据。

流程:

第一步:分析数据网页,该项目只有一页,比较容易分析;

第二步:item,根据数据,修改项目内item.py文件,建立字典的key;

第三步:spider,编写爬虫文件,[spider].py(scrapy genspider spidername ***.con里面的spidername);

第四步:piplines,保存到文件;

第五步:setting,修改User-Agent,robot协议等;

第六步:scrapy runspider [spider].py或者scrapy crwal spidername.

获取b**d**新闻页里的热点新闻标题和对应的url,并保存为.json格式的文件

网页

目的是提取该新闻网站首页的热点新闻里面的标题和标题链接url。代码里获取有上述两类信息的a标签即可存入一个list里面,然后遍历该list从中得到每一个text()和href属性。代码里我们采用xpath的方式,通过分析,<a>标签存在两种不同的xpath路径。

第一种://div[@class=”hotnews”]/ul/li/strong/a

第二种://div[@id=”pane-news”]/ul/li/a

item

根据需求,item有两个字段,依照代码生成的格式来写,如下:

spider

在建立工程时,有些代码已经给我们生成了,不需要修改。爬虫的关键在与这个爬虫类代码。

思路:class里有个 name(爬虫名字) ,allowed_domains(爬取的网站域名),start_urls(初始的url)三个属性,还有一个parse方法,用来编写爬取逻辑的就在这个里面。框架根据start_urls生成一个最初的request对象然后得到response,返回给parse,代码里对该response进行解析,返回item(存储)或者request对象(用来继续发送请求)。代码如下:

说明:确定爬取网页的start_urls,在parse里面进行response解析,返回item和request对象(该项目没有后续页的访问,所以没有yield request)。来看parse,导入iem类的包,在里面声明一个item实例,用于后面的存储和返回,根据分析的xpath路径解析response里面的a标签对象data_list,遍历data_list,得到每一个a标签,然后再次利用xpath获取a标签里面的文本和href,写入item对象,依次返回该item给pipline。

pipline

pipline用于保存文件

将parse获取到的一个个item返回给pipline,通过调用process_item,一个字典一个字典的写入到对应的.json文件中,创建工程时生成的代码只有process_item一个方法,在里面复写了另外两个方法,用于打开和关闭爬虫的操作,代码里在打开和关闭爬虫时同时打开和关闭对应的写入文件,一定不要忘记关闭文件,另外复写open_spider和close_spider时不要忘记spider参数,出现error比较难以发现。

setting

设置访问时的User-Agent和关闭遵守robot协议。

设置访问延时,设置3,即延时3秒访问下一个url或者说request对象。本例子只有一个url访问,设置没什么用,但是已经习惯设置这个了。

运行和结果

开始运行

debug信息

可以看到访问url的结果是200,即为访问成功,同时可以打印出title和对应的url信息,爬取完成后在当前的目录下,可以看到你保存的.json文件,将里面的内容,复制出来进行json格式化查看(直接百度搜索json格式化)。ok,这个就算完成了一个很简单的爬虫项目。

爬取b**d**贴吧里帖子的标题、内容和条数,并保存到.json文件里面

网页

目的是提取朋友贴吧帖子的标题和内容。上述两类信息都在一个<a>标签里面,如下图:

需求即是 title里面的字段和a标签包裹的文本。

开始时候依然采用xpath的方式来获取,但是一直失败,后来检查源代码发现,返回的response里面的html代码是被注释掉的,所以该用正则表达式来提取。感兴趣的同学可以仔细分析下原因,应该是js的缘故。

信息提取(整个a标签)的正则表达式,返回一个list:

data_list = re.compile(r'<a.+href=.+title=.+class=”j_th_tit.+</a>’).findall(response.text)

备注:必须是response.text,body的返回是byte。

item

spider

其他地方和第一个例子基本一致,依然得到该页的所有a标签的list,遍历list,从中提取每一个信息,并返回item。

区别:需求决定了项目的start_urls只是个开始,所有每一页解析完成后,在yield item后,yield了request对象

yield scrapy.Request(url = new_url,callback =self.parse),返回的request对象里面包含新访问的url以及得到response后解析回掉,因为是同一网站,解析是一样的,所以该回掉依然是parse,如果需求的解析是不一样的,可在parse下面再可一个parse方法,比较叫parse2,callback = self.parse2即可。

因为parse里面是yield,所以框架内调用parse时,是不断next的,直到next为空。返回item,引擎就去存储,返回一个request对象,引擎就给调度器。例子里,框架一直next的是一个一个的item(字典),直到item完成,next为request,再次next,即为空了。

记得加上一个return判断,否则将一直爬取下去。代码里只爬取前十页测试一下。

pipline

pipline用于保存文件

采用scrapy里面内置的json导出器来写入。

导入模块:from scrapy.exporters import JsonItemExporter

使用方法:

利用文件对象创建一个exporter对象:exporter_obj = JsonItemExporter(file),注意文件要以byte的方式写入。代码里是’wb’方式。

打开json导出器:exporter_obj.start_exporting()

导出器写入:exporter_obj.export_item(item)

关闭导出器:exporter_obj.finish_exporting()

setting

与上面一样,记得打开管道。

运行和结果

开始运行

debug信息

运行完毕,项目目录里面,会多一个.json文件出来,爬取完毕。

两个爬虫项目就这样结束了,希望可以对scrapy有个初步的使用和了解,后续将继续探讨。

声明:爬虫实例仅供技术讨论,不可用于非法事宜。

https://www.jianshu.com/p/530dab3892ed

Python量化投资网携手4326手游为资深游戏玩家推荐:《《我的世界》:稀有地图种子大公开!僵尸村庄竟然是这样的?

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论