在前面几篇博文当中,我们使用Scrapy
框架编写的爬虫项目,只能爬取起始网址中设置的网页。有时候,我们需要让爬虫持续不断的自动爬取多个网页,此时,我们需要编写自动爬取网页的爬虫。在本章中,我们以我的博客为例,为大家讲解如何编写自动爬取网页的Scrapy
爬虫
我们在使用scrapy startproject blog --nolog
命令创建好爬虫项目之后,首先需要编写items.py
,在该文件中定义好我们关注的需要的数据。我们要爬取的这些网页中包含了大量的数据,但并不是每一样数据我们都关注,如果我们将这些网页所有的数据都存储起来,那么会比较乱并且浪费大量的服务器资源。比如,我们比较关注这些文章中的标题,阅读数, 发布时间等数据,我们可以只提取各网页中每个商品的这5项信息。修改后items.py
文件,代码如下:
import scrapy
class BlogItem(scrapy.Item):
title = scrapy.Field()
page_views = scrapy.Field()
published_date = scrapy.Field()
编写好items.py
后,我们就定义好了需要关注的结构化数据了
编写好items.py
文件之后,还需要对爬取的数据做进一步的处理,比如存储到json文件中,这就要说到Item Pipeline
。当Item
在Spider
中被收集之后,它将会被传递到Item Pipeline
,一些组件会按照一定的顺序执行对Item
的处理。Item Pipeline
主要有以下典型应用:
定制Item Pipeline
的方法其实很简单,每个Item Pipeline
组件是一个独立的Python类,必须实现process_item
方法,方法原型如下:
def process_item(self, item, spider)
每个Item Pipeline
组件都需要调用该方法,这个方法必须返回一个Item
对象,或者抛出DropItem
异常,被丢弃的Item将不会被之后的Pipeline组件所处理。参数说明如下:
我们需要将爬虫爬取的Item存储到本地的json文件中。我们将该爬虫项目中的pipeline.py
文件修改后代码如下:
import json
class BlogPipeline(object):
def __init__(self):
self.file = open("blog.json", 'w', encoding='utf-8')
def process_item(self, item, *args, **kwargs):
for i in range(len(item['title'])):
title = item['title'][i]
page_views = item['page_views'][i]
published_date = item['published_date'][i]
i = json.dumps({'title': title, 'page_views': page_views, 'published_date': published_date}, ensure_ascii=False)
line = i + '\n'
self.file.write(line)
return item
def close_spider(self, *args, **kwargs):
self.file.close()
此时,我们通过pipelines.py
文件将获取到的博客信息存入到了当前目录下的blog.json
文件当中了。
定制完Item Pipeline
,它是无法工作的,需要进行激活。要启用一个Item Pipeline
组件,必须将它的类添加到settings.py
中的ITEM_PIPLINES
变量中,代码如下:
ITEM_PIPELINES = {
'blog.pipelines.BlogPipeline': 300,
}
COOKIES_ENABLED = False # 禁用cookie
设置好settings.py
文件之后,我们需要对该项目中最核心的部分—爬虫文件进行相应的编写,来实现网页的自动爬取以及关键字信息的提取。如下:
import scrapy
from scrapy.http import Request
from blog.items import BlogItem
class BlogSpider(scrapy.Spider):
name = "blog"
allowed_domains = ["csdn.net"]
start_urls = ["https://blog.csdn.net/y472360651/article/list/1"]
def parse(self, response, **kwargs):
item = BlogItem()
res = response.xpath(
'//*[@id="articleMeList-blog"]/div[2]/div/h4/a/text()').extract()
item['title'] = []
for i in res:
i = i.replace('\n', '').replace(' ', '')
if i:
item['title'].append(i)
item['page_views'] = response.xpath('//*[@id="articleMeList-blog"]/div[2]/div/div[1]/p/span[2]/text()').extract()
item['published_date'] = response.xpath('//*[@id="articleMeList-blog"]/div[2]/div/div[1]/p/span[1]/text()').extract()
# 提取完后返回
yield item
# 通过循环自动爬取6页的数据
for i in range(2, 7):
url = f"https://blog.csdn.net/y472360651/article/list/{i}"
# 实现自动爬取
yield Request(url=url, callback=self.parse)
上面的爬虫文件中,关键部分为通过XPath表达式对我们所关注的数据信息进行提取,要爬取的网址的构造以及通过yield
返回Request
实现网页的自动爬取等。
我们可以运行以下该爬虫,如下:
scrapy crawl blog --nolog
运行完成之后,我们可以在当前目录发现一个名为blog.json
的文件,里面就是我们爬取的博客内容啦!
自此,Over~~~