Python中的Scrapy库是一个高效的爬虫框架,用于创建和实现异步的网络爬虫。它提供了一个API来简化爬取网站数据的过程,从而节省开发人员的时间和精力。本篇博客文章将详细介绍Scrapy库的使用和API,并提供相应的代码注释,帮助读者更好地理解它的工作原理和应用场景。
首先我们需要安装Scrapy库,可通过以下命令进行安装:
pip install scrapy
Scrapy主要由以下几个核心组件组成:
Spider是Scrapy库的核心组件之一。它主要负责抓取和解析网页的过程。一个Spider通常包含了从哪里开始抓取、如何抓取、抓取到哪里、如何解析等一系列信息。Scrapy中提供了一个基础的Spider类,开发人员只需创建一个子类,并进行必要的配置即可。
以下是一个简单的Spider示例,它抓取的是全球新闻网站中的新闻标题和链接:
import scrapy
class NewsSpider(scrapy.Spider):
name = 'news'
start_urls = ['https://www.globalnews.ca/world/']
def p****(self, response):
for article in response.css('article[class^="post-"]'):
yield {
'title': article.css('h3[class^="entry-title"] a::text').get(),
'link': article.css('h3[class^="entry-title"] a::attr(href)').get()
}
name
:Spider的名称。单个项目中可能包含多个Spider,通过名称来区分不同的Spider。start_urls
:Spider开始抓取的URL列表。p****
:主要的解析方法,负责从抓取到的HTML中提取有用的信息并进行返回。在上面的示例中,我们通过response
对象提取了网页中所有文章的标题和链接,使用了CSS选择器,并通过关键字yield
将结果返回给Scrapy引擎。
Item是Scrapy库用来表示抓取到的数据的容器。Item中包含了所有需要抓取的数据和每个字段的元数据信息。开发人员只需定义一个Item子类,并进行必要的字段定义即可。
import scrapy
class NewsItem(scrapy.Item):
title = scrapy.Field()
link = scrapy.Field()
在上面的示例中,我们定义了一个NewsItem
类,它包含了两个字段title
和link
。每个字段使用了scrapy.Field()
作为默认值,该字段可包含的类型(如int、float、datetime、string等)将由Scrapy动态确定。
Item Pipeline主要负责将抓取到的数据进行处理、清洗、持久化等操作。它通过一系列的处理器(或过滤器)对Item进行处理,并将处理后的结果发送到存储器中。Item pipeline是Scrapy的一个python类,开发人员可以通过继承和定制来实现自定义的数据处理流程。
以下是一个简单的Item Pipeline示例,它将每个Item存储到JSON文件中:
import json
class NewsPipeline:
def open_spider(self, spider):
self.file = open('news.json', 'w')
def close_spider(self, spider):
self.file.close()
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
在上面的示例中,我们新建了一个NewsPipeline
类,并通过json
模块将Item转换为字典。然后将其存储到文件中。open_spider
和close_spider
方法用于在Spider开启和关闭时创建和销毁文件。process_item
方法则用于定义如何处理Item。
中间件是Scrapy库的另一个核心组件,它主要负责在Spider爬取过程中,对请求和响应之间进行预处理的过程,包括重试、登录验证、代理设置、User-Agent设置等。中间件既可以由Scrapy官方提供,也可以由开发人员自定义。
以下是一个简单的Middleware示例,它用于添加固定的User-Agent:
class NewsMiddleware:
def process_request(self, request, spider):
request.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
在上面的示例中,我们新建了一个NewsMiddleware
类,并重写了process_request
方法,用于添加User-Agent。
在上面了解了Scrapy的核心组件后,我们可以开始实现一个简单的爬虫应用。以下是一个爬取百度百科词条信息的示例爬虫:
在我们开始爬取之前,需要先安装和导入BeautifulSoup模块,该模块将帮助我们解析和提取HTML文档中的信息。
pip install beautifulsoup4
from bs4 import BeautifulSoup
class BaiduBaikeSpider(scrapy.Spider):
name = "baidubaike"
allowed_domains = ["baike.baidu.com"]
start_urls = [
"https://baike.baidu.com/item/Python/407313",
]
def p****(self, response):
soup = BeautifulSoup(response.body, 'html.p****r')
main_content = soup.find('div', {'class': 'main-content'})
title = main_content.find('dd', {'class' : 'lemmaWgt-lemmaTitle-title'}).h1.text.strip()
summary = main_content.find('div', {'class' : 'lemma-summary'}).text.strip()
for paragraph in main_content.select('div[class="para"]'):
content = paragraph.text.strip()
yield {
'title': title,
'summary': summary,
'content': content,
}
在上面的示例中,我们使用了beautifulsoup4
库来解析网页HTML文档,并使用了CSS选择器来提取标题、摘要和正文内容。然后将结果返回给Scrapy引擎。
在完成代码开发后,我们可以使用以下命令启动爬虫并将结果存储到JSON文件中。
scrapy crawl baidubaike -o baidubaike.json
在上面的命令中,baidubaike
是Spider的名称,baidubaike.json
则是存储结果的文件名。
Scrapy是一个高效、可扩展的Python爬虫框架,提供了一些核心组件以便开发人员能够更方便地创建和实现异步网络爬虫。在本文中,我们介绍了Scrapy的核心组件以及如何使用它们来实现一个简单的爬虫应用程序。虽然Scrapy的学习曲线可能较高,但是一旦掌握了它的使用方法,将会大大加快爬虫开发的速度。