Scrapy资料入门教程:新手必读指南
2024/10/25 4:03:04
本文主要是介绍Scrapy资料入门教程:新手必读指南,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Scrapy是一款强大的网络爬虫框架,广泛用于数据抓取和解析。本文详细介绍了Scrapy的安装步骤、项目配置、爬取规则、中间件与管道的使用方法,并提供了实战案例和常见问题的解答,帮助读者更好地理解和使用Scrapy。
Scrapy 是一款用于从网站中抓取数据的强大框架,主要用于构建网络爬虫,以从网页中提取结构化数据。它使用 Python 编写,具有高度可扩展性和灵活性。Scrapy 使用异步、非阻塞的网络爬取方法,使其能够在较少资源的情况下快速抓取大量数据。Scrapy 是一个开源项目,用于构建爬虫以抓取网站并解析数据。它主要用于数据挖掘、信息收集、网络监测等场景。
Scrapy 提供了强大的功能,例如:
- 异步爬取:可以同时发起多个网络请求,提高抓取速度。
- 内置的下载器:可以自定义下载器,支持多种 HTTP 请求方法(如 GET 和 POST)。
- 中间件:可以自定义请求和响应的处理逻辑,例如设置请求头、处理 cookie 等。
- 管道:可以将提取的数据保存到数据库、文件等,实现数据的持久化。
- 调度器:负责管理请求的队列,确保按队列顺序处理请求。
- 选择器:提供了 XPath 和 CSS 选择器,方便提取网页上的数据。
安装 Scrapy 需要 Python 环境,一般推荐使用最新版本的 Python 3。以下是安装步骤:
-
安装 Python 环境
如果您还没有安装 Python,可以从官网下载最新版本的 Python,并按照官方文档进行安装。在安装过程中,请确保选择添加 Python 到 PATH,这样可以在命令行中直接使用 Python。 -
安装 Scrapy
打开命令行工具,输入以下命令安装 Scrapy:pip install scrapy
-
验证安装
安装完成后,可以通过以下命令验证 Scrapy 是否安装成功:scrapy --version
如果安装成功,会显示 Scrapy 的版本号。
-
安装相关依赖库
某些功能可能需要额外的依赖库。例如,安装 lxml 和 cssselect 可以提高选择器的性能:pip install lxml cssselect
- 安装 Scrapy Shell
Scrapy Shell 是一个非常有用的工具,它允许您在没有编写完整爬虫的情况下测试选择器和请求。安装 Scrapy Shell:pip install scrapyshell
创建Scrapy项目后,可以使用 Scrapy Shell 来验证选择器是否能正确提取所需的数据。
创建 Scrapy 项目的步骤如下:
-
创建项目
使用命令行工具(如命令提示符或终端),执行以下命令来创建一个新的 Scrapy 项目:scrapy startproject myproject
这条命令会在当前目录下创建一个名为
myproject
的文件夹,并自动生成一些基本文件和目录结构。项目的基本结构如下:myproject/ ├── myproject/ │ ├── __init__.py │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders/ │ ├── __init__.py │ └── firstSpider.py └── scrapy.cfg
-
创建爬虫
在项目的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
开始抓取数据。 - 运行爬虫
使用以下命令,可以在命令行中运行刚刚创建的爬虫:scrapy crawl firstSpider
Scrapy 提供了一种灵活的方式来配置爬虫的行为。以下是一些常见的配置项:
-
设置元信息
可以在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, }
-
定义请求
在爬虫文件中,定义start_urls
和parse
方法:import scrapy class ExampleSpider(scrapy.Spider): name = 'example' allowed_domains = ['example.com'] start_urls = ['http://example.com/'] def parse(self, response): # 在这里处理响应 pass
- 处理响应
在parse
方法中,可以使用各种方法来处理 HTTP 响应。例如,使用response.css
或response.xpath
提取数据。
Scrapy 使用选择器来解析和提取数据。选择器通过 XPath 或 CSS 选择器来定位网页中的特定部分,从而提取所需的数据。以下是使用选择器的示例:
-
使用 CSS 选择器
CSS 选择器是用于选择 DOM 元素的简洁语法,类似于浏览器开发者工具中的选择器。例如,提取页面中的所有链接:links = response.css('a::attr(href)').getall()
-
使用 XPath 选择器
XPath 是一种强大的查询语言,用于遍历 XML 和 HTML 文档。例如,提取页面中的所有链接:links = response.xpath('//a/@href').getall()
-
提取文本
除了提取链接,还可以提取文本内容。例如,提取页面中的所有段落:paragraphs = response.css('p::text').getall()
- 处理相对路径
页面中的链接通常是相对于页面 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 选择器来提取数据,以下是示例代码:
-
CSS 选择器示例
# 提取所有段落的文本 paragraphs = response.css('p::text').getall() # 提取所有链接的 href 属性 links = response.css('a::attr(href)').getall()
-
XPath 选择器示例
# 提取所有段落的文本 paragraphs = response.xpath('//p/text()').getall() # 提取所有链接的 href 属性 links = response.xpath('//a/@href').getall()
- 选择器方法
除了getall
,还可以使用get
方法来获取第一个匹配结果:first_paragraph = response.css('p::text').get() first_link = response.css('a::attr(href)').get()
Scrapy 中间件提供了扩展框架功能的能力,可以在请求和响应通过 Scrapy 处理过程中进行拦截和修改。以下是中间件的主要应用场景:
-
设置请求头
可以在中间件中设置请求头,如 User-Agent、Cookies 等:class UserAgentMiddleware(object): def process_request(self, request, spider): request.headers['User-Agent'] = 'Mozilla/5.0'
-
处理 Cookies
可以在中间件中设置和处理 Cookies:class CookieMiddleware(object): def process_request(self, request, spider): request.cookies['session'] = '123456'
-
下载器中间件
下载器中间件在请求和响应之间起作用,可以对请求和响应进行自定义处理。例如,添加代理服务器或设置请求头:class MyDownloaderMiddleware(object): def process_request(self, request, spider): # 添加代理服务器 request.meta['proxy'] = 'http://proxy.example.com' return request
-
蜘蛛中间件
蜘蛛中间件在蜘蛛处理请求和响应时介入,例如在请求被调度前或响应被处理前做一些额外的操作: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 中用于处理和存储提取的数据的重要组件。例如,将数据保存到数据库、文件系统等。以下是管道的主要作用和配置方法:
-
定义管道
在myproject/pipelines.py
文件中定义管道类:class MyPipeline(object): def process_item(self, item, spider): # 处理 item 数据 return item
-
启用管道
在settings.py
文件中启用管道:ITEM_PIPELINES = { 'myproject.pipelines.MyPipeline': 300, }
-
保存到数据库
例如,使用 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 请求来抓取数据。可以通过 requests
参数在 Scrapy 爬虫中发起 HTTP 请求。以下是一个示例:
-
发起 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
- 处理请求
在parse
方法中,可以使用yield
关键字发起新的请求,并指定回调函数。回调函数会在新请求的响应返回时调用。
Scrapy 支持自定义请求头和参数。以下是设置请求头和参数的示例:
-
设置请求头
headers = { 'User-Agent': 'Mozilla/5.0', 'Content-Type': 'application/json', } yield scrapy.Request(url, headers=headers, callback=self.parse)
-
设置请求参数
data = { 'param1': 'value1', 'param2': 'value2', } yield scrapy.Request(url, method='POST', body=data, callback=self.parse)
- 使用 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 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-Agent
和 Cookies
都正确。
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 格式。
调试技巧
-
使用 Scrapy Shell
Scrapy Shell 是一个强大的调试工具,可以在不运行完整爬虫的情况下测试选择器和请求:scrapy shell 'http://example.com'
-
打印日志
使用logging
模块或print
语句打印调试信息:import logging logging.warning('This is a warning message')
-
设置日志级别
在settings.py
中设置日志级别,以便获取更多调试信息:LOG_LEVEL = 'DEBUG'
- 使用断点调试
如果使用 IDE(如 PyCharm),可以在代码中设置断点进行调试。例如,使用pdb
模块:import pdb; pdb.set_trace()
通过这些调试技巧,您可以有效地查找并解决 Scrapy 爬虫中的问题。
这篇关于Scrapy资料入门教程:新手必读指南的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-19WebSocket入门指南:轻松搭建实时通信应用
- 2024-11-19Nacos安装资料详解:新手入门教程
- 2024-11-19Nacos安装资料:新手入门教程
- 2024-11-19升级 Gerrit 时有哪些注意事项?-icode9专业技术文章分享
- 2024-11-19pnpm是什么?-icode9专业技术文章分享
- 2024-11-19将文件或目录压缩并保留到指定的固定目录怎么实现?-icode9专业技术文章分享
- 2024-11-19使用 tar 命令压缩文件并且过滤掉某些特定的目录?-icode9专业技术文章分享
- 2024-11-18Nacos安装入门教程
- 2024-11-18Nacos安装入门:轻松掌握Nacos服务注册与配置管理
- 2024-11-18Nacos配置中心入门:新手必读教程