C/C++教程

Scrapy资料入门教程:新手必读指南

本文主要是介绍Scrapy资料入门教程:新手必读指南,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
概述

Scrapy是一款强大的网络爬虫框架,广泛用于数据抓取和解析。本文详细介绍了Scrapy的安装步骤、项目配置、爬取规则、中间件与管道的使用方法,并提供了实战案例和常见问题的解答,帮助读者更好地理解和使用Scrapy。

Scrapy简介与安装
Scrapy是什么

Scrapy 是一款用于从网站中抓取数据的强大框架,主要用于构建网络爬虫,以从网页中提取结构化数据。它使用 Python 编写,具有高度可扩展性和灵活性。Scrapy 使用异步、非阻塞的网络爬取方法,使其能够在较少资源的情况下快速抓取大量数据。Scrapy 是一个开源项目,用于构建爬虫以抓取网站并解析数据。它主要用于数据挖掘、信息收集、网络监测等场景。

Scrapy 提供了强大的功能,例如:

  • 异步爬取:可以同时发起多个网络请求,提高抓取速度。
  • 内置的下载器:可以自定义下载器,支持多种 HTTP 请求方法(如 GET 和 POST)。
  • 中间件:可以自定义请求和响应的处理逻辑,例如设置请求头、处理 cookie 等。
  • 管道:可以将提取的数据保存到数据库、文件等,实现数据的持久化。
  • 调度器:负责管理请求的队列,确保按队列顺序处理请求。
  • 选择器:提供了 XPath 和 CSS 选择器,方便提取网页上的数据。
Scrapy的安装步骤

安装 Scrapy 需要 Python 环境,一般推荐使用最新版本的 Python 3。以下是安装步骤:

  1. 安装 Python 环境
    如果您还没有安装 Python,可以从官网下载最新版本的 Python,并按照官方文档进行安装。在安装过程中,请确保选择添加 Python 到 PATH,这样可以在命令行中直接使用 Python。

  2. 安装 Scrapy
    打开命令行工具,输入以下命令安装 Scrapy:

    pip install scrapy
  3. 验证安装
    安装完成后,可以通过以下命令验证 Scrapy 是否安装成功:

    scrapy --version

    如果安装成功,会显示 Scrapy 的版本号。

  4. 安装相关依赖库
    某些功能可能需要额外的依赖库。例如,安装 lxml 和 cssselect 可以提高选择器的性能:

    pip install lxml cssselect
  5. 安装 Scrapy Shell
    Scrapy Shell 是一个非常有用的工具,它允许您在没有编写完整爬虫的情况下测试选择器和请求。安装 Scrapy Shell:
    pip install scrapyshell

创建Scrapy项目后,可以使用 Scrapy Shell 来验证选择器是否能正确提取所需的数据。

Scrapy项目与爬虫的基本配置
创建Scrapy项目

创建 Scrapy 项目的步骤如下:

  1. 创建项目
    使用命令行工具(如命令提示符或终端),执行以下命令来创建一个新的 Scrapy 项目:

    scrapy startproject myproject

    这条命令会在当前目录下创建一个名为 myproject 的文件夹,并自动生成一些基本文件和目录结构。项目的基本结构如下:

    myproject/
    ├── myproject/
    │   ├── __init__.py
    │   ├── items.py
    │   ├── middlewares.py
    │   ├── pipelines.py
    │   ├── settings.py
    │   └── spiders/
    │       ├── __init__.py
    │       └── firstSpider.py
    └── scrapy.cfg
  2. 创建爬虫
    在项目的 myproject/spiders 目录下,创建一个新的爬虫文件。例如,创建一个名为 firstSpider.py 的文件,并在其中定义一个新的爬虫:

    import scrapy
    
    class FirstSpiderSpider(scrapy.Spider):
       name = 'firstSpider'
       allowed_domains = ['example.com']
       start_urls = ['http://example.com/']
    
       def parse(self, response):
           pass

    这个爬虫将从 example.com 开始抓取数据。

  3. 运行爬虫
    使用以下命令,可以在命令行中运行刚刚创建的爬虫:
    scrapy crawl firstSpider
配置Scrapy爬虫

Scrapy 提供了一种灵活的方式来配置爬虫的行为。以下是一些常见的配置项:

  1. 设置元信息
    可以在 settings.py 文件中设置爬虫的元信息。例如,设置爬虫的名称、延迟时间、用户代理等:

    BOT_NAME = 'myproject'
    
    SPIDER_MODULES = ['myproject.spiders']
    NEWSPIDER_MODULE = 'myproject.spiders'
    
    # 限制下载延迟
    DOWNLOAD_DELAY = 1
    
    # 设置用户代理
    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
    
    # 启用的中间件
    DOWNLOADER_MIDDLEWARES = {
       'myproject.middlewares.MyCustomDownloaderMiddleware': 543,
    }
    
    # 启用的管道
    ITEM_PIPELINES = {
       'myproject.pipelines.MyPipeline': 300,
    }
  2. 定义请求
    在爬虫文件中,定义 start_urlsparse 方法:

    import scrapy
    
    class ExampleSpider(scrapy.Spider):
       name = 'example'
       allowed_domains = ['example.com']
       start_urls = ['http://example.com/']
    
       def parse(self, response):
           # 在这里处理响应
           pass
  3. 处理响应
    parse 方法中,可以使用各种方法来处理 HTTP 响应。例如,使用 response.cssresponse.xpath 提取数据。
Scrapy的爬取规则
解析和提取数据

Scrapy 使用选择器来解析和提取数据。选择器通过 XPath 或 CSS 选择器来定位网页中的特定部分,从而提取所需的数据。以下是使用选择器的示例:

  1. 使用 CSS 选择器
    CSS 选择器是用于选择 DOM 元素的简洁语法,类似于浏览器开发者工具中的选择器。例如,提取页面中的所有链接:

    links = response.css('a::attr(href)').getall()
  2. 使用 XPath 选择器
    XPath 是一种强大的查询语言,用于遍历 XML 和 HTML 文档。例如,提取页面中的所有链接:

    links = response.xpath('//a/@href').getall()
  3. 提取文本
    除了提取链接,还可以提取文本内容。例如,提取页面中的所有段落:

    paragraphs = response.css('p::text').getall()
  4. 处理相对路径
    页面中的链接通常是相对于页面 URL 的相对路径。使用 response.urljoin 方法可以将相对路径转换为绝对路径:
    absolute_url = response.urljoin(link)

完整项目实例:从网站抓取新闻标题和链接

假设我们需要从 example.com 抓取新闻标题和链接,创建一个新的 Scrapy 项目 news_scraper

scrapy startproject news_scraper

news_scraper/spiders 目录下,创建一个名为 news_spider.py 的文件:

import scrapy

class NewsSpider(scrapy.Spider):
    name = 'news'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/news']

    def parse(self, response):
        for article in response.css('div.article'):
            title = article.css('h2.title::text').get()
            link = article.css('a::attr(href)').get()

            yield {
                'title': title,
                'link': link,
            }

        next_page = response.css('a.next::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)

settings.py 中,设置一些基本配置:

DOWNLOAD_DELAY = 1
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'

运行爬虫:

scrapy crawl news

使用XPath和CSS选择器

Scrapy 选择器使用 XPath 和 CSS 选择器来提取数据,以下是示例代码:

  1. CSS 选择器示例

    # 提取所有段落的文本
    paragraphs = response.css('p::text').getall()
    
    # 提取所有链接的 href 属性
    links = response.css('a::attr(href)').getall()
  2. XPath 选择器示例

    # 提取所有段落的文本
    paragraphs = response.xpath('//p/text()').getall()
    
    # 提取所有链接的 href 属性
    links = response.xpath('//a/@href').getall()
  3. 选择器方法
    除了 getall,还可以使用 get 方法来获取第一个匹配结果:
    first_paragraph = response.css('p::text').get()
    first_link = response.css('a::attr(href)').get()
Scrapy的中间件与管道
中间件的使用场景

Scrapy 中间件提供了扩展框架功能的能力,可以在请求和响应通过 Scrapy 处理过程中进行拦截和修改。以下是中间件的主要应用场景:

  1. 设置请求头
    可以在中间件中设置请求头,如 User-Agent、Cookies 等:

    class UserAgentMiddleware(object):
       def process_request(self, request, spider):
           request.headers['User-Agent'] = 'Mozilla/5.0'
  2. 处理 Cookies
    可以在中间件中设置和处理 Cookies:

    class CookieMiddleware(object):
       def process_request(self, request, spider):
           request.cookies['session'] = '123456'
  3. 下载器中间件
    下载器中间件在请求和响应之间起作用,可以对请求和响应进行自定义处理。例如,添加代理服务器或设置请求头:

    class MyDownloaderMiddleware(object):
       def process_request(self, request, spider):
           # 添加代理服务器
           request.meta['proxy'] = 'http://proxy.example.com'
           return request
  4. 蜘蛛中间件
    蜘蛛中间件在蜘蛛处理请求和响应时介入,例如在请求被调度前或响应被处理前做一些额外的操作:

    class MySpiderMiddleware(object):
       def process_request(self, request, spider):
           # 在请求发送前做一些操作
           return None
    
       def process_response(self, response, request, spider):
           # 在响应处理前做一些操作
           return response

完整项目实例:配置和使用中间件

假设我们需要在请求中加入一个固定的 User-Agent,可以在 myproject/middlewares.py 文件中定义一个中间件:

class UserAgentMiddleware(object):
    def process_request(self, request, spider):
        request.headers['User-Agent'] = 'Mozilla/5.0'

settings.py 文件中启用该中间件:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.UserAgentMiddleware': 543,
}

管道的作用与配置

管道(Pipelines)是 Scrapy 中用于处理和存储提取的数据的重要组件。例如,将数据保存到数据库、文件系统等。以下是管道的主要作用和配置方法:

  1. 定义管道
    myproject/pipelines.py 文件中定义管道类:

    class MyPipeline(object):
       def process_item(self, item, spider):
           # 处理 item 数据
           return item
  2. 启用管道
    settings.py 文件中启用管道:

    ITEM_PIPELINES = {
       'myproject.pipelines.MyPipeline': 300,
    }
  3. 保存到数据库
    例如,使用 SQLite 数据库保存数据:

    import sqlite3
    
    class SqlitePipeline(object):
       def __init__(self):
           self.conn = sqlite3.connect('data.db')
           self.c = self.conn.cursor()
           self.c.execute('''CREATE TABLE IF NOT EXISTS items (title text, link text)''')
    
       def process_item(self, item, spider):
           self.c.execute("INSERT INTO items VALUES (?, ?)", (item['title'], item['link']))
           self.conn.commit()
           return item
    
       def close_spider(self, spider):
           self.conn.close()

完整项目实例:配置和使用管道

假设我们需要将抓取的数据保存到 SQLite 数据库,可以在 myproject/pipelines.py 文件中定义一个管道:

import sqlite3

class SqlitePipeline(object):
    def __init__(self):
        self.conn = sqlite3.connect('data.db')
        self.c = self.conn.cursor()
        self.c.execute('''CREATE TABLE IF NOT EXISTS items (title text, link text)''')

    def process_item(self, item, spider):
        self.c.execute("INSERT INTO items VALUES (?, ?)", (item['title'], item['link']))
        self.conn.commit()
        return item

    def close_spider(self, spider):
        self.conn.close()

settings.py 文件中启用该管道:

ITEM_PIPELINES = {
    'myproject.pipelines.SqlitePipeline': 300,
}
Scrapy的下载器与请求
发起HTTP请求

Scrapy 使用 HTTP 请求来抓取数据。可以通过 requests 参数在 Scrapy 爬虫中发起 HTTP 请求。以下是一个示例:

  1. 发起 GET 请求

    import scrapy
    
    class ExampleSpider(scrapy.Spider):
       name = 'example'
       allowed_domains = ['example.com']
       start_urls = ['http://example.com/']
    
       def parse(self, response):
           # 发起 GET 请求
           yield scrapy.Request('http://example.com/page', callback=self.parse_page)
    
           # 发起 POST 请求
           yield scrapy.Request('http://example.com/post', method='POST', body='data=123', callback=self.parse_post)
    
       def parse_page(self, response):
           # 处理 GET 请求响应
           pass
    
       def parse_post(self, response):
           # 处理 POST 请求响应
           pass
  2. 处理请求
    parse 方法中,可以使用 yield 关键字发起新的请求,并指定回调函数。回调函数会在新请求的响应返回时调用。
设置请求头与参数

Scrapy 支持自定义请求头和参数。以下是设置请求头和参数的示例:

  1. 设置请求头

    headers = {
       'User-Agent': 'Mozilla/5.0',
       'Content-Type': 'application/json',
    }
    yield scrapy.Request(url, headers=headers, callback=self.parse)
  2. 设置请求参数

    data = {
       'param1': 'value1',
       'param2': 'value2',
    }
    yield scrapy.Request(url, method='POST', body=data, callback=self.parse)
  3. 使用 FormRequest
    如果需要发送表单数据,可以使用 FormRequest 类:
    yield scrapy.FormRequest(url, formdata={'username': 'user', 'password': 'pass'}, callback=self.parse_login)

完整项目实例:发起HTTP请求

假设我们需要从 example.com 发起一个 GET 请求并抓取数据,可以在 news_scraper/spiders 目录下创建一个名为 http_request_spider.py 的文件:

import scrapy

class HttpRequestSpider(scrapy.Spider):
    name = 'http_request'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/']

    def parse(self, response):
        # 发起 GET 请求
        yield scrapy.Request('http://example.com/page', callback=self.parse_page)

    def parse_page(self, response):
        # 处理 GET 请求响应
        pass

settings.py 文件中设置延迟时间:

DOWNLOAD_DELAY = 1

运行爬虫:

scrapy crawl http_request
Scrapy的实战应用与调试技巧
实战案例分析

下面是一个完整的 Scrapy 实战案例,用于从一个网站抓取新闻标题和链接。

创建项目

scrapy startproject news_scraper

创建爬虫

news_scraper/spiders 目录下创建一个名为 news_spider.py 的文件,并定义爬虫:

import scrapy

class NewsSpider(scrapy.Spider):
    name = 'news'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/news']

    def parse(self, response):
        for article in response.css('div.article'):
            title = article.css('h2.title::text').get()
            link = article.css('a::attr(href)').get()

            yield {
                'title': title,
                'link': link,
            }

        next_page = response.css('a.next::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)

运行爬虫

在命令行中执行以下命令运行爬虫:

scrapy crawl news

保存数据

news_scraper/pipelines.py 中定义一个管道:

import json

class NewsScraperPipeline(object):
    def __init__(self):
        self.file = open("items.json", "w")

    def process_item(self, item, spider):
        line = json.dumps(dict(item)) + "\n"
        self.file.write(line)
        return item

    def close_spider(self, spider):
        self.file.close()

配置管道

settings.py 中启用管道:

ITEM_PIPELINES = {
   'news_scraper.pipelines.NewsScraperPipeline': 300,
}
常见问题解答与调试方法

在使用 Scrapy 进行网络爬取时,可能会遇到一些常见的问题。以下是一些常见问题的解答和调试方法:

问题:抓取速度过快,被服务器限制

解答:可以设置 DOWNLOAD_DELAY 参数来减缓抓取速度,避免被服务器封锁:

DOWNLOAD_DELAY = 1  # 1 秒延迟

问题:请求被重定向

解答:可以在 settings.py 中设置 REDIRECT_ENABLED 参数为 False,并使用 response.meta['redirect_urls'] 获取重定向 URL。

REDIRECT_ENABLED = False

问题:请求被拒绝

解答:检查请求头是否正确设置,确保 User-AgentCookies 都正确。

headers = {
    'User-Agent': 'Mozilla/5.0',
    'Cookies': 'session=123456',
}

问题:XPath 或 CSS 选择器提取错误

解答:使用 Scrapy Shell 来验证选择器是否正确:

scrapy shell 'http://example.com'

然后在 Shell 中测试选择器:

response.css('div.article').getall()

问题:数据格式不正确

解答:检查数据项是否符合预期格式,并确保管道正确处理数据。例如,使用 json 库将数据保存为 JSON 格式。

调试技巧

  1. 使用 Scrapy Shell
    Scrapy Shell 是一个强大的调试工具,可以在不运行完整爬虫的情况下测试选择器和请求:

    scrapy shell 'http://example.com'
  2. 打印日志
    使用 logging 模块或 print 语句打印调试信息:

    import logging
    
    logging.warning('This is a warning message')
  3. 设置日志级别
    settings.py 中设置日志级别,以便获取更多调试信息:

    LOG_LEVEL = 'DEBUG'
  4. 使用断点调试
    如果使用 IDE(如 PyCharm),可以在代码中设置断点进行调试。例如,使用 pdb 模块:
    import pdb; pdb.set_trace()

通过这些调试技巧,您可以有效地查找并解决 Scrapy 爬虫中的问题。

这篇关于Scrapy资料入门教程:新手必读指南的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!