实验目的
- 掌握python中获取网页的基本库,解析网页的基本方法。
- 掌握使用Scrapy等爬虫工具编写爬虫程序的基本思路。
- 掌握抓取列表+详情的静态组合页面的方法。
实验要求
- 抓取目标。可以选择以下网站作为抓取目标,也可以寻找自己感兴趣的抓取目标:
1)“李开复的博客”:http://blog.sina.com.cn/kaifulee
2)腾讯公益:http://gongyi.qq.com
3)人民网滚动新闻:http://news.people.com.cn - 任务要求。
1) 分析页面结构,确定待抓取的数据项,抓取文章标题、发表时间、正文内容、文章URL、作者、新闻来源、责编
评分标准:满分35分;每个数据项5分,能够获取主要数据项4项,30分,抓取额外数据项目2项以上给满分;
2) 正确处理目录页面和正文页面,能够自动抓取至少100篇网页内容。
评分标准:满分25分;每20条数据5分,根据爬取的数量给分超过100篇,满分;
3) 数据持久化。将数据存入磁盘文件,Scrapy可以参考下列文章:
https://blog.csdn.net/qy20115549/article/details/52575291
评分标准:满分20分;根据无写入,写入文本或Excel,写入数据库确定分数;无写入0分,写入文本或Excel 10分;写入数据库20;
4) 数据处理
评分标准:满分15分;提到数据处理5分;每个数据处理问题5分,解决两个以上数据处理问题的给予15分;
5) 报告整体情况:
评分标准:报告格式整洁程度5分;
加分:实验报告中未要求的但在实验过程中发现新的问题,每个加5分,不超过10分。
实验程序及运行结果
实验内容概述
本程序使用scrapy架构,共采集6页李开复博客目录与252篇博文信息,实现了数据清洗处理,在控制台输出问题数据,并将修改后的数据分别存入mongodb数据库和csv文件,其间有进度条显示程序运行进度。
代码解说
(温馨提示:本文为实验报告,其中代码为方便呈现稍有改动,代码完整版位于github上,选择版本:爬虫-1)
翻页:通过回调函数实现翻页。
def parse(self, response):
# 翻页
next_url = response.xpath("//div[@class='SG_page']/ul/li[@class='SG_pgnext']/a/@href").extract_first()
if next_url is not None:
yield scrapy.Request(next_url, callback=self.parse, dont_filter=True)
pass
显示页数:利用response.xpath获得当前页数。
由于添加了进度条,这块代码被注释,使控制台输出更美观。
# 显示当前页数
num_url = response.xpath("//div[@class='SG_page']/ul/li[@class='SG_pgon']/text()").extract_first()
print("\n正在爬取第", num_url, "页")
爬取目录页:标题、时间、链接。
链接用于爬取动态数据与详情页,数据存在item1(MuLuItem)。
node_list = response.xpath('//div[@class="articleList"]')
for node in node_list:
item1 = MuLuItem()
# 爬取目录页(标题、时间、链接)
if node.xpath('//p[@class="atc_main SG_dot"]/span[2]/a/text()').extract():
item1['标题'] = node.xpath('//p[@class="atc_main SG_dot"]/span[2]/a/text()').extract()
if node.xpath('//p[@class="atc_info"]/span[2]/text()').extract():
item1['时间'] = node.xpath('//p[@class="atc_info"]/span[2]/text()').extract()
if node.xpath('//p[@class="atc_main SG_dot"]/span[2]/a/@href').extract():
item1['链接'] = node.xpath('//p[@class="atc_main SG_dot"]/span[2]/a/@href').extract()
yield item1
爬取动态数据:阅读数,喜欢数,评论数,转发数,收藏数。
利用item1的链接组合得到动态数据api,调用函数爬虫,数据存在item2(ShuJvItem),利用if判断是否为空,非空才爬。
# 爬取详情页数据
for num in range(len(item1['链接'])):
w = str(item1['链接'][num][-21:-13])
q = str(item1['链接'][num][-11:-5])
detail_url = 'http://comet.blog.sina.com.cn/api?maintype=num&uid=' + w + '&aids=' + q
item2 = ShuJvItem()
item2['链接'] = 'http://blog.sina.com.cn/s/blog_' + w + '01' + q +