Scrapy爬取知乎热榜信息

本文介绍了使用Scrapy框架爬取知乎热榜信息的过程,包括新建Scrapy项目、定义数据结构、编写spider、编辑管道和中间件文件。Scrapy的特点在于模块化、速度快,并提供了方便的数据处理流程。在实践中,作者遇到并解决了爬取过程中遇到的问题,如异常处理和Cookie配置,最终成功实现了知乎热榜的爬取并展示了爬取结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前两周去学习了一下Django,由于第一次接触设计模式,对于mvc设计模式还是很陌生的,花了大约一周的时间才大概熟悉了整个工作流程,第二周学会了写一些简单的网站应用,原本自己定好目标是要两周学会一个框架的,但是整网站要搞服务器,还要域名备案什么的,怪麻烦的,两周时间过去,还是没有做一个完整的Django项目,也就没脸跑去写博客来记录了。但还是不得不继续学习我计划中的下一个框架——Scrapy,从3.15到今天3.21号已经正好过去一周了,我花了四到五天的时间看完了一本半的书,周五晚上熬了个夜最终把整个scrapy项目的流程写了一遍,包括spideritem管道spider中间件下载器中间件。由于笔者之前已经对爬虫有一定的经验了,因此这个框架接触的比较快。

1.Scrapy的特点

要具体去说scrapy的特点,网上故居一搜一大堆,而且也比我写的更准确具体详细,我也只是写下来作为自己的笔记。有错误的话也欢迎各位指正。
1.1 在我看来,在大概了解了scrapy框架之后,我唯一的感受就是模块化,就像是我之前写的爬虫都是啥玩意,各种工作都糅杂在一起,一个方法写解析主页,一个方法写构造表单数据,一个方法写详情页的解析,又一个方法写数据的保存等等,很多地方都有重复性工作,比如爬取网站上的文章,主页爬一遍,详情页又爬一遍,相当于request写了两遍,但其实这个过程是一样的,request的作用不就是用来请求得到html吗,虽然请求头有所不同,但是这个过程是没必要去写两遍的。
1.2 另一个感受就是脉络清晰,scrapy将各种功能的实现都模块化了,也因此让我们不再考虑一个项目的具体实现,只需要写它的业务逻辑便是了。就那上面爬取网站文章的例子来说。首先定义它的数据结构,要保存哪些数据,比如标题日期作者文章标签文章内容,那么首先在item.py文件里定义好字段。在网站主页上我们只能获得文章的标题日期,因此对于文章的作者文章标签文章内容我们还需要进入详情页进行分析,此时就已经简单确定好了spider的业务逻辑。分别写parse方法和parse_xqy方法,在parse方法里获取文章的标题时间,随后返回一个Request对象给下载器,meta属性里传递item对象,callback属性写上详情页解析方法的方法名parse_xqy,在parse_xqy里面获取文章的作者文章标签文章内容,将数据合并成一个item对象,返回item对象管道。至此,一个项目的主体已然实现了,而剩下的就是管道中对item对象的处理,中间件对Request对象Response对象异常的处理 。
1.3 速度快,scrapy的调度器采用了twisted异步框架,可以让我们的项目不受到部分任务因此网络或者其他原因而阻塞,而且scrapy的调度器里的请求队列也实现的挺好的(但具体怎么好我也不清楚,本人只是用技术而不造技术的渣渣),对于大批量的请求,我自己写的爬虫可能根本承受不了,但是scrapy却可以很轻松的承受。而且更快更稳。

2.一个小项目

废话不多说,实战开始,我先简单写个爬取一下知乎首页文章

2.1 新建scrapy项目

打开控制台,输入

scrapy startproject zhihu [zhihu]

zhihu表示项目名,方括号里后面表示文件夹名。

2.2 新建爬虫

这一步在上一步的基础上

cd zhihu
scrapy genspider zhihutext zhihu.com

当然,你也可以直接进入spiders文件夹新建爬虫文件,但是这样需要自己写一下下面的内容

import scrapy


class ZhihutextSpider(scrapy.Spider):
    name = 'zhihu'
    allowed_domains = ['zhihu.com']
    start_urls = ['http://zhihu.com/hot']

    def parse(self, response):
        pass

ZhihutextSpider继承自scrapy.Spider,有一些属性和方法,有些属性和方法需要重写,以实现对特定网站的爬取。

2.2.1 属性

name
对一个spider来说,name属性时必须且唯一的,其定义了spider的名字,而scrapy通过spider的名字来定位并且初始化spider。

allowed_domains
该属性可选,该属性是一个列表,里面是域名,表示爬虫只会爬属于域名列表里面的网页。

start_urls
也是一个列表,当没有指定特定url时,spider将从该列表中开始获取页面数据,后续的url将从获取的数据中提取。

custom_setings
该属性可选,是一个dict。当spider启动时,会覆盖项目的设置,即setting.py文件里面的设置,由于设置必须在初始化前被更新,因此必须设定为class属性。

2.2.2方法

start_requests()方法
在爬虫启动时,scrapy会调用该方法,会从start_urls列表里面一次获取url并生成Request对象传递给下载器,中间经历了spider中间件下载器中间件,下载器下载返回了Response对象,然后调用parse()方法解析Response对象,该方法一般可以选择不重写。

parse()方法
该方法是爬虫最重要的部分,该方法接收一个response参数,即从下载器中下载的Response对象。该方法是一定要重写的(不过有一个例外,scrapy自带的通用爬虫CrawlSpider是一定不能重写此方法的,原因是CrawlSpider默认使用parse来实现爬虫逻辑,如果重写了parse,那么CrawlSpider将不能继续正确执行),也是我们写爬虫最重要的一个地方,我们从Response对象中提取数据就是在该方法里。

2.3 定义数据结构(编写items.py文件)

在这里插入图片描述
分析页面,主页上有排行榜排名,问题,简介和热度。
在这里插入图片描述
进入一个问题详情页里面,发现有标签,关注者,被浏览,问题内容,回答数,评论数。
因此我们可以在items.py里定义9个字段:
top_numberquestionquestion_contenthottagsattentionbrowseanswer_numbercomment_number

import scrapy


class ZhihuItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    top_number = scrapy.Field()
    question = scrapy.Field()
    question_content = scrapy.Field()
    hot = scrapy.Field()
    tags = scrapy.Field()
    attention = scrapy.Field()
    browse = scrapy.Field()
    answer_number = scrapy.Field()
    comment_number = scrapy.Field()

2.4 编写spider文件

import scrapy
from zhihu.items import ZhihuItem
from scrapy import Request
import json, re

class ZhihutextSpider(scrapy.Spider):
    name = 'zhihu'
    # allowed_domains = ['zhihu.com']
    start_urls = ['http://zhihu.com/hot']

    def start_requests(self):
        for url in self.start_urls:
            yield Request(url, callback=self.parse)

    def parse(self, response):
        selectors 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值