使用 Scrapy 收集数据
先决条件:
- 刮痧
- SQLite3
Scrapy是一个网页抓取库,用于抓取、解析和收集网页数据。现在,一旦我们的蜘蛛抓取了数据,它就会决定是否:
- 保留数据。
- 删除数据或项目。
- 停止并存储处理后的数据项。
因此,对于所有这些功能,我们有一个pipelines.py文件,用于通过按顺序执行的各种组件(称为类)处理抓取的数据。在本文中,我们将通过pipelines.py 文件学习,如何使用SQLite3 数据库语言收集scrapy 抓取的数据。
初始化目录并设置项目
首先,让我们创建一个scrapy项目。为此,请确保系统中安装了Python和 PIP。然后一一运行下面给出的命令来创建一个类似于我们将在本文中使用的项目的scrapy项目。
- 让我们首先在名为 GFGScrapy 的文件夹中创建一个虚拟环境,并在那里激活该虚拟环境。
# To create a folder named GFGScrapy
mkdir GFGScrapy
cd GFGScrapy
# making virtual env there.
virtualenv .
cd scripts
# activating it.
activate
cd..
输出:
- 现在是时候创建一个scrapy项目了。为此确保系统中是否安装了scrapy。如果未安装,请使用下面给定的命令安装它。
句法:
pip install scrapy
现在要创建一个scrapy项目,使用下面给定的命令并创建一个蜘蛛。
# project name is scrapytutorial
scrapy startproject scrapytutorial
cd scrapytutorial
# link is of the website we are looking to crawl
scrapy genspider spider_to_crawl https://quotes.toscrape.com
使用 pip 安装程序创建了一个 scrapy 项目后,项目目录的输出看起来就像图像中给出的那样。
Scrapy 目录结构
目录结构由以下路径组成(示例)
C:///
在上图中,项目名称是scrapytutorial,里面有很多文件,如图所示。
- 我们感兴趣的文件是spider_to_crawl.py文件(我们用来描述蜘蛛的方法)和pipelines.py文件,我们将在其中描述将处理我们将使用抓取的数据完成的进一步数据处理的组件.简单来说,这个文件用来描述进一步操作数据的方法。
- 第三个最重要的文件是settings.py文件,我们将在其中有序注册我们的组件(在管道中创建,.py 文件)。
- 下一个最重要的文件是items.py 文件。此文件用于描述数据将从spider_to_crawl 流向pipelines.py 文件的表单或字典结构。在这里,我们将提供一些将出现在每个项目中的键。
使用 Scrapy 收集数据
让我们看看蜘蛛文件夹中的spider_to_crawl.py文件。这是我们编写蜘蛛必须抓取的 URL 的文件,还有一个名为 parse() 的方法,用于描述应该对蜘蛛抓取的数据做什么。
这个文件是由上面使用的“ scrapy genspider ”命令自动生成的。该文件以蜘蛛的名字命名。下面给出的是生成的默认文件。
笔记:
- 请注意,我们对上述默认文件进行了一些更改,即注释掉了 allowed_domains 行,并且我们还对 start_urls 进行了一些更改(删除了“http://” )。
- 我们不需要在我们的系统中安装 SQLite3,因为它与Python一起预安装。因此,我们可以导入它并开始使用它。
因为现在我们已经准备好我们的项目,所以现在我们可以继续看看 pipelines.py 文件是如何实现来存储蜘蛛抓取的数据的。
项目管道是一种管道方法,它写在pipelines.py文件中,用于对抓取的数据按顺序执行下面给出的操作。下面列出了我们可以对抓取的项目执行的各种操作:
- 解析抓取的文件或数据。
- 将抓取的数据存储在数据库中。
- 将文件从一种格式转换为另一种格式。例如到 JSON。
为了对项目执行不同的操作,我们必须声明一个单独的组件(文件中的类),它由各种方法组成,用于执行操作。默认的管道文件有一个以项目名称命名的类。我们还可以创建自己的类来编写它们必须执行的操作。如果任何管道文件包含多个类,我们应该明确提及它们的执行顺序。
操作是按顺序执行的,所以我们使用settings.py文件来描述操作应该执行的顺序。即我们可以提到首先执行哪个操作,接下来执行哪个操作。这通常在我们对项目执行多个操作时完成。
每个组件(类)必须有一个名为process_item() 的默认函数,它是始终在管道文件的类或组件内部调用的默认方法。
Syntax:
process_item( self, item, spider )
Parameters:
- self : This is reference to the self object calling the method.
- item : These are the items list scraped by the spider
- spider : mentions the spider used to scrape.
The return type of this method is the modified or unmodified item object or an error will be raised if any fault is found in item.
This method is also used to call other method in this class which can be used to modify or store data.
除此之外,我们还可以定义自己的方法(例如 init() 等)来执行其他任务,例如创建数据库来存储数据或编写将数据转换为其他形式的代码。
pipelines.py 的工作
现在让我们看看 pipelines.py 是如何工作的:
- 首先,我们的蜘蛛将抓取网络数据并使用其解析方法从中创建项目(在 items.py 文件中描述)。然后将这些项目传递给 pipelines.py 文件。
- 接收到items后,pipelines文件会按照settings.py文件中提到的顺序调用自身描述的所有组件。这些组件使用它们的默认函数来处理数据项。
- 因此,处理完成后,下一个数据项将从蜘蛛传输,并且相同的现象一直持续到网络抓取完成。
注册组件
重要的是将我们在项目管道文件中创建的所有组件注册到名为 ITEM_PIPELINES 的目录结构中的 settings.py 文件中。
句法:
ITEM_PIPELINES = {
myproject.pipelines.component :
#many other components
}
这里的优先级编号是scrapy调用组件的顺序。
创建要通过文件传递的项目
需要注意的另一件事是,我们将需要在 items.py 文件中描述我们的项目将包含的内容。因此我们的 items.py 文件包含以下给定的代码:
Python3
# Define here the models for your scraped items
import scrapy
class ScrapytutorialItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# only one field that it of Quote.
Quote = scrapy.Field()
Python3
import scrapy
# importing the items structure described
# in items.py file
from ..items import ScrapytutorialItem
class SpiderToCrawlSpider(scrapy.Spider):
name = 'spider_to_crawl'
#allowed_domains = ['https://quotes.toscrape.com/']
start_urls = ['https://quotes.toscrape.com/']
def parse(self, response):
# creating items dictionary
items = ScrapytutorialItem()
# this is selected by pressing ctrl+f in console
# and selecting the appropriate rule of Xpath
Quotes_all = response.xpath('//div/div/div/span[1]')
# These paths are based on the selectors
for quote in Quotes_all: # extracting data
items['Quote'] = quote.css('::text').extract()
yield items
# calling pipelines components for further
# processing.
Python3
from itemadapter import ItemAdapter
import sqlite3
class ScrapytutorialPipeline(object):
# init method to initialize the database and
# create connection and tables
def __init__(self):
# Creating connection to database
self.create_conn()
# calling method to create table
self.create_table()
# create connection method to create database
# or use database to store scraped data
def create_conn(self):
# connecting to database.
self.conn = sqlite3.connect("mydata.db")
# collecting reference to cursor of connection
self.curr = self.conn.cursor()
# Create table method using SQL commands to create table
def create_table(self):
self.curr.execute("""DROP TABLE IF EXISTS firsttable""")
self.curr.execute("""create table firsttable(
Quote text
)""")
# store items to databases.
def process_item(self, item, spider):
self.putitemsintable(item)
return item
def putitemsintable(self, item):
# extracting item and adding to table using SQL commands.
self.curr.execute("""insert into firsttable values (?)""", (
item['Quote'][0],
))
self.conn.commit() # closing the connection.
我们将要求将此文件导入到我们的 spider_to_crawl.py 文件中。因此,通过这种方式,我们可以创建要传递给管道的项目。现在我们清楚管道的概念及其工作方式。
实现 SQLite3
现在是时候学习如何在Python实现 SQLite3 来创建数据库和表了。
- 首先,我们将创建init()方法,因为它在任何Python类中首先被调用。因此在这个函数,我们将提到调用其他名为: create_conn()和create_table() 的方法来分别创建数据库的连接和表。
- 现在在create_conn() 中,我们将使用 SQLite 类的connect()方法连接(如果不存在则创建)到上述数据库。
- 在create_table() 中,我们编写了 SQL 命令,并告诉连接的游标引用执行该命令以创建表。
- 最后process_item()方法将被调用(默认),该方法调用另一个方法,该方法又将抓取的项目数据放入在init()中创建的表中。
因此,通过这种方式,我们可以将数据存储在数据库中。为了可视化收集的数据,我们必须在线使用 SQLite,因为默认情况下,我们的系统无法打开此类文件。如果你安装了一些帮助软件,那么你就不需要这个了。
现在我们准备好进入示例。在这个例子中,我们将使用我们学到的所有上述技术,并为我们的抓取数据创建一个数据库。我们将使用上述站点抓取行情数据,并使用 pipelines.py 文件中的 SQLite3 将其存储在我们的数据库中。所以我们将使用如何在Python实现SQLite3的想法来创建一个管道,该管道将从蜘蛛抓取中接收数据并将该数据插入到创建的数据库中的表中。那么让我们开始在spider_to_crawl.py文件中编写代码。在这里,我们声明了我们的蜘蛛并提供所需的 URL 作为输入,以便蜘蛛可以抓取它。
Spider_to_crawl.py:
蟒蛇3
import scrapy
# importing the items structure described
# in items.py file
from ..items import ScrapytutorialItem
class SpiderToCrawlSpider(scrapy.Spider):
name = 'spider_to_crawl'
#allowed_domains = ['https://quotes.toscrape.com/']
start_urls = ['https://quotes.toscrape.com/']
def parse(self, response):
# creating items dictionary
items = ScrapytutorialItem()
# this is selected by pressing ctrl+f in console
# and selecting the appropriate rule of Xpath
Quotes_all = response.xpath('//div/div/div/span[1]')
# These paths are based on the selectors
for quote in Quotes_all: # extracting data
items['Quote'] = quote.css('::text').extract()
yield items
# calling pipelines components for further
# processing.
我们现在添加下面的管道方法,这些方法将写入 pipelines.py 文件,以便创建数据库。
管道.py文件
蟒蛇3
from itemadapter import ItemAdapter
import sqlite3
class ScrapytutorialPipeline(object):
# init method to initialize the database and
# create connection and tables
def __init__(self):
# Creating connection to database
self.create_conn()
# calling method to create table
self.create_table()
# create connection method to create database
# or use database to store scraped data
def create_conn(self):
# connecting to database.
self.conn = sqlite3.connect("mydata.db")
# collecting reference to cursor of connection
self.curr = self.conn.cursor()
# Create table method using SQL commands to create table
def create_table(self):
self.curr.execute("""DROP TABLE IF EXISTS firsttable""")
self.curr.execute("""create table firsttable(
Quote text
)""")
# store items to databases.
def process_item(self, item, spider):
self.putitemsintable(item)
return item
def putitemsintable(self, item):
# extracting item and adding to table using SQL commands.
self.curr.execute("""insert into firsttable values (?)""", (
item['Quote'][0],
))
self.conn.commit() # closing the connection.
Items.py和settings.py文件应如下所示:
在此之后,使用给定的命令来抓取和收集数据。
句法:
scrap crawl filename
使用命令“scrapy crawl spider_to_crawl”后,处理将采用给定的方式:
- 在spider.py中我们提到了我们的spider应该去那个站点并提取URL格式中提到的所有数据的代码,然后将创建它的项目列表并将该列表传递给pipelines.py文件以供进一步处理。
- 我们还创建了一个 items 对象来包含要传递的数据,并将其注册到目录中的items.py文件中。
- 然后当蜘蛛爬行时,它会收集 items 对象中的数据并将其传输到管道,接下来发生的事情已经从上面的代码中清楚地看到了,并在注释中给出了提示。 pipelines.py文件创建一个数据库并存储所有传入的项目。
这里调用init()方法,该方法总是在任何Python文件中作为默认方法调用。然后它调用用于创建表和初始化数据库的所有其他方法。
然后process_item()方法用于调用名为putitemintable()的方法,该方法将数据存储在数据库中。然后执行该方法后,将引用返回给蜘蛛,以传递其他要操作的项目。
让我们看看抓取引号后存储数据的输出。
输出:
因此,通过这种方式,我们能够在数据库中有效地收集网络数据。