利用Scrapy爬取糗事百科段子
2016-06-30 08:57
573 查看
之前用BeautifulSoup爬过糗事百科段子,但效率太低,自从使用了Scrapy框架以后,爬取大量信息再也不是事儿。今天要用这个强大的框架来爬取段子们,并将它们保存到本地的json文件中。
创建好项目后,首先考虑要爬取的内容,为了简洁这里只爬取作者和段子信息,可以根据需要设置其他对象如点赞数、评论数等 。
pipelines.py与上篇文章中机票爬虫相同,均要保存为可显示中文的json文件。
同时,修改settings.py中的代码如下:
此次所用的爬虫与上次不同,只爬单个页面是不够的,要让它自己往链接上去探索新的世界。scrapy提供了一个爬虫类CrawlSpider可以胜任这项工作。
这个爬虫类可以设定爬取规则rules,allow中为所规定让它继续爬取的网页的正则表达式,这里设定爬取糗事百科中的hot中的所有帖子。需要注意的是,当使用这个爬虫类时,不可重写parse函数 ,start_urls的回调函数变为了parse_item。rules规则中的callback亦用其作为回调函数,因为处理的页面是相同的,follow=True表示在start_urls之后的网页亦进行如上规则的爬取操作。
接下来输入scrapy crawl qsbk。结果,出现了问题!
速度非常快,快得不正常,查看看到的json文件及scrapy log发现只爬到了第一页的内容,而其他的均是503状态码,被ban掉了,真的是命途多舛。查看scrapy文档,发现需要在settings.py中设置一个下载延迟。
这告诉我们,爬虫不能下载得太暴力,有时得慢慢来。经实验发现,当该值较小时,比如0.1,0.25时,爬到的段子量与其成正相关,当大到一定值,比如上面的1S时,段子量不再增加,应该是爬到了所有hot区的段子。
细心的朋友可能发现,这网站的hot区有35页,一页21个段子,爬到的总段子量却有2040之多。经研究后发现,对于该网站,http://www.qiushibaike.com/hot/page/4/?s=4890821 这样网址的内容与http://www.qiushibaike.com/hot/page/4/ 中的内容是完全不同的。强大的scrapy应该将它们全部爬了下来。
scrapy startproject qiushibaike
创建好项目后,首先考虑要爬取的内容,为了简洁这里只爬取作者和段子信息,可以根据需要设置其他对象如点赞数、评论数等 。
import scrapy class QiushibaikeItem(scrapy.Item): author = scrapy.Field() duanzi = scrapy.Field()
pipelines.py与上篇文章中机票爬虫相同,均要保存为可显示中文的json文件。
import codecs,json class QiushibaikePipeline(object): def __init__(self): self.file = codecs.open('qsbk.json', 'wb', encoding='utf-8') def process_item(self, item, spider): line = json.dumps(dict(item)) + '\n' self.file.write(line.decode("unicode_escape")) return item
同时,修改settings.py中的代码如下:
BOT_NAME = 'qiushibaike' SPIDER_MODULES = ['qiushibaike.spiders'] NEWSPIDER_MODULE = 'qiushibaike.spiders' USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1' ITEM_PIPELINES = { 'qiushibaike.pipelines.QiushibaikePipeline': 300, }
此次所用的爬虫与上次不同,只爬单个页面是不够的,要让它自己往链接上去探索新的世界。scrapy提供了一个爬虫类CrawlSpider可以胜任这项工作。
# -*- encoding: utf-8 -*- __author__ = 'fybhp' from qiushibaike.items import QiushibaikeItem from scrapy.spiders import CrawlSpider,Rule from scrapy.linkextractors import LinkExtractor class QiushibaikeSpider(CrawlSpider): name = "qsbk" allowed_domains = ["qiushibaike.com"] start_urls = ['http://www.qiushibaike.com/hot/'] rules = [ Rule(LinkExtractor(allow=r'http://www.qiushibaike.com/hot/.*?'), callback='parse_item', follow=True), ] def parse_item(self,response): for sel in response.xpath('//div[@class="article block untagged mb15"]'): item = QiushibaikeItem() item['author'] = sel.xpath('.//h2/text()')[0].extract() item['duanzi'] = sel.xpath('div[@class="content"]/text()').extract() yield item
这个爬虫类可以设定爬取规则rules,allow中为所规定让它继续爬取的网页的正则表达式,这里设定爬取糗事百科中的hot中的所有帖子。需要注意的是,当使用这个爬虫类时,不可重写parse函数 ,start_urls的回调函数变为了parse_item。rules规则中的callback亦用其作为回调函数,因为处理的页面是相同的,follow=True表示在start_urls之后的网页亦进行如上规则的爬取操作。
接下来输入scrapy crawl qsbk。结果,出现了问题!
速度非常快,快得不正常,查看看到的json文件及scrapy log发现只爬到了第一页的内容,而其他的均是503状态码,被ban掉了,真的是命途多舛。查看scrapy文档,发现需要在settings.py中设置一个下载延迟。
DOWNLOAD_DELAY = 1
这告诉我们,爬虫不能下载得太暴力,有时得慢慢来。经实验发现,当该值较小时,比如0.1,0.25时,爬到的段子量与其成正相关,当大到一定值,比如上面的1S时,段子量不再增加,应该是爬到了所有hot区的段子。
细心的朋友可能发现,这网站的hot区有35页,一页21个段子,爬到的总段子量却有2040之多。经研究后发现,对于该网站,http://www.qiushibaike.com/hot/page/4/?s=4890821 这样网址的内容与http://www.qiushibaike.com/hot/page/4/ 中的内容是完全不同的。强大的scrapy应该将它们全部爬了下来。
相关文章推荐
- Python3写爬虫(四)多线程实现数据爬取
- install and upgrade scrapy
- install scrapy with pip and easy_install
- Scrapy的架构介绍
- 爬虫笔记
- 使用 Python 处理 JSON 格式的数据
- XML 与 JSON 优劣对比
- VBA将excel数据表生成JSON文件
- newtonsoft.json解析天气数据出错解决方法
- 基于C#实现网页爬虫
- vbs 解析json jsonp的方法
- Ruby和Ruby on Rails中解析JSON格式数据的实例教程
- Extjs4如何处理后台json数据中日期和时间
- C#实现将类的内容写成JSON格式字符串的方法
- JQuery ajax返回JSON时的处理方式 (三种方式)
- jquery JSON的解析方式示例介绍
- Nodejs爬虫进阶教程之异步并发控制
- c#版json数据解析示例分享
- ASP JSON类文件的使用方法