【Scrapy04】进化!01号爬虫

本文介绍02号爬虫,在01爬虫基础上,进入文章链接解析详细内容。先分析页面,得到解析规则,接着自定义解析函数,重写相关函数以控制跳转。完成爬虫后给出运行结果和源码,还简单介绍了爬虫中Python的super()和yield特色用法。

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

在知道了01爬虫的运行原理之后,现在能让其去做更多的事情,在上一节中已经拿到了页面上所有文章的链接,现在可以进入每一条链接,可以拿到文章的详细内容,对其进行一一解析,这就是本文的内容,02号爬虫。

  • 分析页面

首先访问优快云博客主页:https://blog.youkuaiyun.com/

按照01号爬虫的解析规则,解析出每一篇文章的详细链接。然后依次访问链接,进入文章的详情页面,解析内容为:标题,时间,阅读数。

想要解析文章的内容,当然是可以的,只不过文章的内容太多,不方便显示,所以此处不解析文章的内容,感兴趣的朋友可以自行去测试。下图为例子:

查看页面元素,依照xpath的原理,得到如下解析规则:

‘title’://div[@class=’article-header’]//div//h1/text()

‘time’://span[@class=‘time’]/text()

‘readcount’://span[@class=’read-count’]/text()

至此,得到了页面内容的解析规则。

  • 解析函数

我们需要优先解析博客首页的那些文章链接。可以自定义一个解析函数_url_parse(self,response),response用于接收返回的response对象。

这个函数需要做两件事情,1,从页面中解析文章链接;2,对解析出来的链接发送请求。解析链接没有什么问题,问题在于如何对解析得到的链接发送新请求。在上一篇文章中提到了Request函数。可以直接用Request发送请求。

Request方法当然是没有问题的,但是,事实上爬虫所继承的scarpy.Spider中有一个函数,之前也提到过,那就是make_requests_from_url(self, url),本质上它就是在调用Request函数,所以,重写它即可,还有一个原因就是,爬虫启动,访问self.start_urls的起始链接列表时,调用的也是这个函数,我们需要“控制”它跳转到_url_parse(self,response),而不是跳转到默认的parse(self,response)函数

先将make_requests_from_url(self, url)函数重写,让它访问博客首页时,回调到我们自定义的_url_parse(self,response)。

def make_requests_from_url(self, url):
    """ This method is deprecated. """
    return Request(url,dont_filter=True,callback=self. _url_parse)

只需要将request的callback属性指定成我们的自定义函数即可。直接给callback赋定值似乎不够灵活,我们后续可能会继续调用make_requests_from_url(self, url),让它回调到别的函数。因此需要一个自定义变量self. custom_way,在初始化函数中给它赋初始值

重写初始化函数:

def __init__(self,name=None, **kwargs):
    self.custom_way = self._url_parse
    super(myspider02,self).__init__()

重写make_requests_from_url(self, url):

def make_requests_from_url(self, url):
    """ This method is deprecated. """
    return Request(url,dont_filter=True,callback=self.custom_way)

这时可以完成_url_parse(self,response)函数,让它解析出新的链接,访问新的链接,并且回调到另一个函数_content_parse(self,response)(这个函数用于解析页面中想要的数据)。

完成_url_parse(self,response)函数:

def _url_parse(self,response):
    print('正在解析url')
    hrefs=response.selector.xpath('//div[@class="title"]//h2//a/@href').extract()
    print(hrefs)
    self.custom_way = self._content_parse
    for href in hrefs:
        yield self.make_requests_from_url(href)

更改回调函数的方式就是,更改self. custom_way的值。现在去完成页面解析函数_content_parse(self,response)即可,比较简单,不需要单独贴出来,请在下面的完整源码中查看。

这样,整个爬虫也就完成了。以下是运行结果和完整的源码。

运行结果:

 

02号爬虫源码如下,windows记事本的话记得另存文件为utf-8:

#coding=utf-8
import scrapy
from scrapy.http import Request
class myspider02(scrapy.Spider):
    name='02'
    start_urls=['https://blog.youkuaiyun.com/']
    def __init__(self,name=None, **kwargs):
        self.custom_way = self._url_parse
        super(myspider02,self).__init__()
   
    def make_requests_from_url(self, url):
        """ This method is deprecated. """
        return Request(url,dont_filter=True,callback=self.custom_way)

    def _content_parse(self,response):
        print('正在解析文章内容!'+response.url)
        title=response.selector.xpath('//div[@class="article-header"]//div//h1/text()').extract()
        time=response.selector.xpath('//span[@class="time"]/text()').extract()
        readcount=response.selector.xpath('//span[@class="read-count"]/text()').extract()
        print('题名:',title)
        print('时间:',time)
        print('阅读数量:',readcount) 
   
    def _url_parse(self,response):
        print('正在解析url')
        hrefs=response.selector.xpath('//div[@class="title"]//h2//a/@href').extract()
        print(hrefs)
        self.custom_way = self._content_parse
        for href in hrefs:
            yield self.make_requests_from_url(href)
  • 关于python

在这个爬虫中用到了两个python语言比较有特色的用法。

一个是,super()函数的使用。

一个是,yield的用法。

如果要解释清楚,需要一定的篇幅,因为与scrapy无关,这里只简单介绍一下。

Super()用于调用超类的方法,所传递的参数为,类名和对象,此处为myspider02和self。我们通过它调用了scrapy.Spider的初始函数,所以scrapy.Spider中没有被重写的方法,依旧可以正常使用。

Yield用于生成器,拥有yield的函数,就是一个生成器,它和return有很大的区别,生成器一次只返回一个结果。例如return返回一个列表,那么yield只是逐个返回列表里的内容,在很多程序中,这样占用资源少(但是人们普遍还是用return),在scrapy中发起请求时,会要求你返回一个request,item或者其他等等,此时最好用yield。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值