Scrapy 是一个基于 Python 的强大爬虫框架,主要用于高效地抓取网站数据并进行结构化处理。它具有异步处理、模块化、易扩展、高性能等特点。
安装 Scrapy :
pip install scrapy
在终端命令行进入 python 交互编程模式,检查是否能导入 scrapy 模块:
>>> import scrapy
>>> scrapy.version_info
(2, 13, 3)
>>>
然后退出 python 交互编程模式,即在命令行输入 scrapy 命令;
PS C:\Users\Think\Desktop> scrapy
Scrapy 2.13.3 - no active project
Usage:
scrapy <***mand> [options] [args]
Available ***mands:
bench Run quick benchmark test
fetch Fetch a URL using the Scrapy downloader
genspider Generate new spider using pre-defined templates
runspider Run a self-contained spider (without creating a project)
settings Get settings values
shell Interactive scraping console
startproject Create new project
version Print Scrapy version
view Open URL in browser, as seen by Scrapy
[ more ] More ***mands available when run from project directory
Use "scrapy <***mand> -h" to see more info about a ***mand
编写第一个Scrapy爬虫
项目需求是从 http://books.toscrape.*** 网站爬取书籍名称、价格。
第1步创建 scrapy 项目:
$ scrapy startproject example
root@DESKTOP-D5J8UKO:/mnt/e/pyobject/spider2025# tree example/
example/
├── example
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ └── settings.cpython-311.pyc
│ ├── items.py
│ ├── middlewares.py
│ ├── pipelines.py
│ ├── settings.py
│ └── spiders
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ ├── book_spider.cpython-311.pyc
│ │ └── books.cpython-311.pyc
│ └──
└── scrapy.cfg
第2步分析页面:
<li class="col-xs-6 col-sm-4 col-md-3 col-lg-3">
<article class="product_pod">
<div class="image_container">
<a href="catalogue/a-light-in-the-attic_1000/index.html"><img src="media/cache/2c/da/2cdad67c44b002e7ead0***35693c0e8b.jpg" alt="A Light in the Attic" class="thumbnail"></a>
</div>
<p class="star-rating Three">
<i class="icon-star"></i>
<i class="icon-star"></i>
<i class="icon-star"></i>
<i class="icon-star"></i>
<i class="icon-star"></i>
</p>
<h3><a href="catalogue/a-light-in-the-attic_1000/index.html" title="A Light in the Attic">A Light in the ...</a></h3>
<div class="product_price">
<p class="price_color">£51.77</p>
<p class="instock availability">
<i class="icon-ok"></i>
In stock
</p>
<form>
<button type="submit" class="btn btn-primary btn-block" data-loading-text="Adding...">Add to basket</button>
</form>
</div>
</article>
</li>
每一本书的信息包裹在<article class="product_pod">元素中:书名信息在其下h3 > a元素的title属性中,如<a href="catalogue/a-light-in-the-attic_1000/index.html"title="A Light in the Attic">A Light in the ...</a>;书价信息在其下<p class="price_color">元素的文本中,如<p class="price_color">£51.77</p>
下一页的URL在ul.pager > li.next > a元素的href属性中,是一个相对URL地址,如<li class="next"><a href="catalogue/page-2.html">next</a></li>
第3步 实现 Spider 类编写代码
# -*- codeing:utf-8 -*-
import scrapy
class BooksSpider(scrapy.Spider):
name = 'books'
start_urls = ['http://books.toscrape.***/']
def parse(self, response):
"""
解析响应数据,提取书籍名称和价格信息,并处理下一页请求
:param response: Scrapy发送请求后返回的响应对象,包含网页数据
:yield: 生成包含书籍名称和价格的字典对象
:yield: 如果存在下一页,生成下一页的请求对象
"""
# 遍历响应中的每个书籍元素
for book in response.css('article.product_pod'):
# 提取书籍名称
name = book.xpath('.//h3/a/@title').extract_first()
# 提取书籍价格
price = book.css('p.price_color::text').extract_first()
# 生成并返回包含书籍名称和价格的字典
yield {
'name': name,
'price': price,
}
# 提取下一页的URL
next_url = response.css('li.next a::attr(href)').extract_first()
# 如果下一页URL存在,则生成并返回下一页的请求
if next_url:
next_url = response.urljoin(next_url)
yield scrapy.Request(next_url, callback=self.parse)
- name属性一个Scrapy项目中可能有多个爬虫,每个爬虫的name属性是其自身的唯一标识,在一个项目中不能有同名的爬虫,本例中的爬虫取名为’books’。
- start_urls属性一个爬虫总要从某个(或某些)页面开始爬取,我们称这样的页面为起始爬取点,start_urls属性用来设置一个爬虫的起始爬取点。在本例中只有一个起始爬取点’http://books.toscrape.***’。
- parse方法当一个页面下载完成后,Scrapy引擎会回调一个我们指定的页面解析函数(默认为parse方法)解析页面。一个页面解析函数通常需要完成以下两个任务:
- ➢ 提取页面中的数据(使用XPath或CSS选择器)。
- ➢ 提取页面中的链接,并产生对链接页面的下载请求。
页面解析函数通常被实现成一个生成器函数,每一项从页面中提取的数据以及每一个对链接页面的下载请求都由yield语句提交给Scrapy引擎。
第4步运行爬虫
$ scrapy crawl books -o books.csv