针对这个主题,我可以提供一份针对“python爬虫scrapy框架之增量式爬虫的示例代码”的完整攻略。
什么是增量式爬虫?
在介绍示例代码之前,我们先来了解一下什么是“增量式爬虫”。简单来说,增量式爬虫就是针对已经抓取过的内容进行增量的、增量的更新;只爬取新加入的,而不是全盘的重新抓取。对于时间线较为敏感的数据应用,增量式爬虫可以减少开销,提高数据更新速度。
增量式爬虫的工作原理
在 Scrapy 爬虫框架中,实现增量式爬虫的基本思路是通过判断页面的“更新时间、修改时间”等信息,以此来判断页面是否需要重新抓取。具体的实现方式,可以通过在 Request 对象中添加 etag、Last-Modified 、If-Modified-Since 等头部信息,在请求时携带上次页面的时间信息,服务端会根据这些时间信息,判断页面是否已更新,然后返回更新状态。根据状态来判断是否需要重新抓取。
示范代码
示例 #1:增量爬取百度百科“机器学习”下的关键词条
首先,从 Python爬虫Scrapy框架入门教程 这里复制一个简单的 Scrapy 代码,用于爬取百度百科下的“机器学习”条目:
import scrapy
class BaiduBaikeSpider(scrapy.Spider):
name = 'baidu_baike'
allowed_domains = ['baike.baidu.com']
start_urls = ['https://baike.baidu.com/item/机器学习']
def parse(self, response):
for item in response.xpath('//div[@class="main-content"]'):
print(item.xpath('.//text()').extract())
接着,为了实现增量爬虫功能,我们需要在 Spider 实例化的时候进行初始化设置:
import scrapy
from scrapy.http import Request
class BaiduBaikeSpider(scrapy.Spider):
name = 'baidu_baike'
allowed_domains = ['baike.baidu.com']
start_urls = ['https://baike.baidu.com/item/机器学习']
etag, last_modified = None, None
def start_requests(self):
headers = {
'If-None-Match': self.etag,
'If-Modified-Since': self.last_modified
}
yield Request(url=self.start_urls[0], headers=headers)
def parse(self, response):
# 判断返回的状态是不是 304,如果是 304 代表没有新版本
if response.status == 304:
print('没有新内容,直接返回即可')
return
self.etag = response.headers.get('ETag').decode('utf-8')
self.last_modified = response.headers.get('Last-Modified').decode('utf-8')
for item in response.xpath('//div[@class="main-content"]'):
print(item.xpath('.//text()').extract())
通过初始化 etag
、last_modified
两个变量,来记录上一次爬取数据的状态。 在第一次请求时,etag
和 last_modified
均为 None
,并为 Spider 设置 start_requests()
函数。在此函数中,为请求添加 If-None-Match
和 If-Modified-Since
头部信息,以便服务端判断是否有新版本可用。
在解析页面之后,判断返回的状态码是否为 304,如果是 304 代表没有新版本,不需要再次进行爬取即可返回。
示例 #2:增量爬取新浪新闻的新闻标题
下面再放一个爬取新浪新闻的示例,爬取的内容是新闻标题。具体代码如下:
import scrapy
from scrapy.http import Request
class SinaSpider(scrapy.Spider):
name = 'sina'
allowed_domains = ['news.sina.com.cn']
start_urls = ['http://news.sina.com.cn/']
etag, last_modified = None, None
def start_requests(self):
headers = {
'If-None-Match': self.etag,
'If-Modified-Since': self.last_modified
}
yield Request(url=self.start_urls[0], headers=headers)
def parse(self, response):
if response.status == 304:
print('没有新内容,直接返回即可')
self.etag = response.headers.get('ETag').decode('utf-8')
self.last_modified = response.headers.get('Last-Modified').decode('utf-8')
for item in response.css('h2 a::text').extract():
print(item.strip())
该示例的工作原理和示例 #1 相同。不过,注意到这里的解析器采用了 CSS Selector ,而不是上述示例中使用的 XPath 。
总结
通过这两个示例可以看出,Scrapy 框架的增量爬虫功能并没有像我们想象的那么难。只要我们在构建 Scraper 实例时,添加好上次爬取结果的状态信息,在请求时也带上上次请求结果的时间信息,并在解析器中进行状态和时间的更新,就可以实现增量式爬虫啦。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python爬虫scrapy框架之增量式爬虫的示例代码 - Python技术站