Scrapy
是一个用于爬取网站数据、提取结构性数据的开源和协作框架。它最初是为网页抓取设计的,但也可以用于获取 API 提供的数据或作为通用的网络爬虫。
文章目录
- 主要特性
- 主要组件
- 使用流程
- 1. 安装 Scrapy
- 2. 创建 Scrapy 项目
- 3. 定义 Item(数据)
- 4. 创建和编写 Spiders 文件
- 5. 修改 settings.py 文件
- 6. 运行 Scrapy 爬虫
- 运行项目生成文件说明
- 1. `scrapy.cfg`
- 2. `myproject/`
- a. `__init__.py`
- b. `items.py`
- c. `middlewares.py`
- d. `pipelines.py`
- e. `settings.py`
- 3. `myproject/spiders/`
- a. `__init__.py`
- b. `myspider.py`
- 数据存储
- 1. 文件存储
- a. JSON 文件
- b. CSV 文件
- 2. 数据库存储
- a. SQLite
- b. MySQL
- c. MongoDB
- 3. 其他存储方式
- a. Elasticsearch
- b. Amazon S3
主要特性
- 异步处理:Scrapy 使用 Twisted 异步网络库,可以高效处理多个并发请求。
- 内置支持选择器:Scrapy 内置支持 XPath 和 CSS 选择器来提取数据。
- 数据管道:提供数据处理管道,可以对抓取的数据进行清洗、验证和存储。
- 中间件:支持下载中间件和爬虫中间件,可以在请求和响应处理过程中插入自定义逻辑。
- 扩展性:可以通过编写扩展和中间件来扩展 Scrapy 的功能。
- 支持多种输出格式:可以将抓取的数据导出为 JSON、CSV、XML 等格式。
- 自动限速:内置支持自动限速,可以防止对目标网站造成过大压力。
主要组件
- Spider(爬虫):定义如何抓取某个网站或一组网站,包括如何执行抓取(即跟进链接)以及如何从页面中提取结构化数据。
- Item(项目):定义抓取的数据结构,类似于 Python 中的字典,但提供了更强的类型检查和验证。
- Item Pipeline(项目管道):负责处理被抓取的项目,通常包括数据清洗、验证和存储。
- Downloader Middleware(下载中间件):处理请求和响应的钩子框架,可以用于修改、丢弃或重试请求。
- Spider Middleware(爬虫中间件):处理爬虫的输入(响应)和输出(请求和项目)的钩子框架。
使用流程
Scrapy 是一个强大的 Python 爬虫框架,用于从网站中提取数据。以下是从创建项目到运行爬虫的详细步骤:
1. 安装 Scrapy
首先,需要安装 Scrapy。可以使用 pip 进行安装:
pip install scrapy
2. 创建 Scrapy 项目
使用以下命令创建一个新的 Scrapy 项目:
scrapy startproject myproject
这将在当前目录下创建一个名为 myproject
的文件夹,包含 Scrapy 项目的结构。
3. 定义 Item(数据)
Item 是用来定义要从网页中提取的数据结构。在 myproject/items.py
文件中定义 Item:
import scrapy
class MyItem(scrapy.Item):
# 定义字段
name = scrapy.Field()
description = scrapy.Field()
4. 创建和编写 Spiders 文件
Spider 是 Scrapy 中用于定义如何抓取网站的类。在 myproject/spiders
目录下创建一个新的 Spider 文件,例如 myspider.py
:
import scrapy
from myproject.items import MyItem
class MySpider(scrapy.Spider):
name = "myspider"
start_urls = [
'http://example.com',
]
def parse(self, response):
for item in response.css('div.item'):
my_item = MyItem()
my_item['name'] = item.css('h1::text').get()
my_item['description'] = item.css('p::text').get()
yield my_item
5. 修改 settings.py 文件
在 myproject/settings.py
文件中,可以配置 Scrapy 的各种设置,例如 USER_AGENT、ROBOTSTXT_OBEY 等:
BOT_NAME = 'myproject'
SPIDER_MODULES = ['myproject.spiders']
NEWSPIDER_MODULE = 'myproject.spiders'
USER_AGENT = 'Mozilla/5.0 (compatible; MyProject/1.0; +http://example.com)'
ROBOTSTXT_OBEY = True
6. 运行 Scrapy 爬虫
使用以下命令运行的 Spider:
scrapy crawl myspider
这将启动 myspider
并开始抓取数据。
运行项目生成文件说明
1. scrapy.cfg
这是项目的配置文件,通常位于项目的根目录下。它主要用于定义项目的部署配置。
[settings]
default = myproject.settings
[deploy]
#url = http://localhost:6800/
project = myproject
2. myproject/
这是项目的主目录,包含了项目的所有代码和配置文件。
a. __init__.py
这是一个空文件,用于标识 myproject
目录是一个 Python 包。
b. items.py
这个文件用于定义爬虫抓取的数据结构,即 Item。Item 类似于数据库中的表结构,用于存储爬取到的数据字段。
import scrapy
class MyItem(scrapy.Item):
name = scrapy.Field()
description = scrapy.Field()
c. middlewares.py
这个文件用于定义自定义的中间件。中间件可以用于处理请求和响应,例如添加自定义的 HTTP 头、处理重定向等。
class MyCustomMiddleware(object):
def process_request(self, request, spider):
request.headers['User-Agent'] = 'MyCustomUserAgent'
return None
d. pipelines.py
这个文件用于定义数据处理管道。管道用于在数据被爬取后进行处理,例如清洗数据、验证数据、存储数据等。
class MyPipeline(object):
def process_item(self, item, spider):
# 处理 item 的逻辑
return item
e. settings.py
这个文件包含了项目的所有配置。可以在这里设置爬虫的行为,例如设置 User-Agent、启用中间件、配置管道等。
BOT_NAME = 'myproject'
SPIDER_MODULES = ['myproject.spiders']
NEWSPIDER_MODULE = 'myproject.spiders'
USER_AGENT = {}
ROBOTSTXT_OBEY = True
ITEM_PIPELINES = {
'myproject.pipelines.MyPipeline': 300,
}
3. myproject/spiders/
这个目录用于存放爬虫的代码。可以在这里创建多个爬虫文件,每个文件定义一个爬虫。
a. __init__.py
这是一个空文件,用于标识 spiders
目录是一个 Python 包。
b. myspider.py
这是一个示例爬虫文件,用于定义如何抓取网站的数据。
import scrapy
class MySpider(scrapy.Spider):
name = "myspider"
start_urls = [
'http://example.com',
]
def parse(self, response):
for item in response.css('div.item'):
yield {
'name': item.css('h1::text').get(),
'description': item.css('p::text').get(),
}
数据存储
1. 文件存储
a. JSON 文件
JSON 是一种轻量级的数据交换格式,易于阅读和编写。
import json
def process_item(item):
with open('data.json', 'a') as f:
line = json.dumps(dict(item)) + "\n"
f.write(line)
return item
b. CSV 文件
CSV 文件是一种简单的表格数据存储格式。
import csv
def process_item(item):
with open('data.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow(item.values())
return item
2. 数据库存储
a. SQLite
SQLite 是一种嵌入式数据库,适合小型项目。
import sqlite3
def process_item(item):
conn = sqlite3.connect('data.db')
c = conn.cursor()
c.execute("INSERT INTO items VALUES (?, ?)", (item['name'], item['description']))
conn.commit()
conn.close()
return item
b. MySQL
MySQL 是一种流行的关系型数据库,适合大型项目。
import mysql.connector
def process_item(item):
conn = mysql.connector.connect(user='user', password='password', host='host', database='database')
c = conn.cursor()
c.execute("INSERT INTO items (name, description) VALUES (%s, %s)", (item['name'], item['description']))
conn.commit()
conn.close()
return item
c. MongoDB
MongoDB 是一种 NoSQL 数据库,适合存储非结构化数据。
from pymongo import MongoClient
def process_item(item):
client = MongoClient('localhost', 27017)
db = client['mydatabase']
collection = db['items']
collection.insert_one(dict(item))
return item
3. 其他存储方式
a. Elasticsearch
Elasticsearch 是一个基于 Lucene 的搜索引擎,适合存储和搜索大量数据。
from elasticsearch import Elasticsearch
def process_item(item):
es = Elasticsearch()
es.index(index='items', doc_type='item', body=dict(item))
return item
b. Amazon S3
Amazon S3 是一种云存储服务,适合存储大量文件。
import boto3
def process_item(item):
s3 = boto3.client('s3')
s3.put_object(Bucket='mybucket', Key='data.json', Body=json.dumps(dict(item)))
return item