前言
最近在 B 站上学习了 Python 爬虫的相关知识,发现了一个非常强大且好用的现代爬虫框架 ------ Scrapling 。相比于传统的 requests + BeautifulSoup,它不仅内置了强大的防反爬机制(StealthyFetcher),还对提取数据的 API 做了极大的优化,甚至自带了类似 Scrapy 的异步爬虫结构,但配置却简单得多。
今天就结合刚学的教程,带大家实战演练一下:如何用 Scrapling 爬取豆瓣电影 Top250,并一键保存为 JSON 数据。
一、 环境准备
在开始之前,请确保你的 Python 环境中安装了 scrapling:
pip install scrapling
二、 基础实战:爬取单部电影详情 (demo.py)
在直接爬取 Top250 列表之前,我们先拿豆瓣电影的详情页(以《肖申克的救赎》为例)练练手,体验一下 Scrapling 的无头浏览器能力。
豆瓣的反爬机制有时会拦截普通的请求,但 Scrapling 的 StealthyFetcher 可以完美模拟真实浏览器绕过限制。
代码实现:
from scrapling import StealthyFetcher
# 1. 实例化隐身抓取器
fetcher = StealthyFetcher()
# 2. 发起请求并绕过反爬
page = fetcher.fetch(
url='https://movie.douban.com/subject/1292052/',
google_search=False, # 是否模拟从谷歌搜索跳转
real_chrome=True, # 启用真实 Chrome 浏览器指纹模拟
wait_selector="#info" # 等待指定元素加载完毕,确保页面渲染完成
)
# 3. 使用优雅的 CSS 选择器提取数据
title = page.css("h1 span::text").get()
year = page.css("span.year::text").get()
rating = page.css("span.rating_num::text").get()
# get_all_text() 可以直接提取该节点下所有的纯文本
info = page.css("#info").first.get_all_text()
# getall() 返回列表
shorts = page.css(".short::text").getall()
# 打印结果
print(title, year, rating, info)
print(shorts)
技术拆解:
real_chrome=True: 这是 Scrapling 的杀手锏之一,能够有效应对各种盾和基础反爬。page.css(): 语法与 Scrapy 非常相似,支持伪类如::text直接获取文本,比 BS4 更加简洁。
三、 进阶实战:异步爬取 Top250 全站 (Spider.py)
掌握了基础抓取后,我们开始真正的 Top250 爬取。为了提高效率,我们将使用 Scrapling 的异步 Spider 模块,它允许我们并发请求,并且能轻松处理翻页逻辑。
代码实现:
from scrapling.spiders import Spider, Request, Response
class MovieSpider(Spider):
# 爬虫名称
name = "movie"
# 起始 URL
start_urls = ["https://movie.douban.com/top250"]
# 设置并发请求数为 10,大幅提升爬取速度
concurrent_requests = 10
async def parse(self, response: Response):
# 1. 解析当前页的每一部电影卡片
for card in response.css('.item'):
yield {
"title": card.css('.title::text').get(),
# .clean() 是 Scrapling 的便捷方法,自动去除多余的换行和空格
"info": card.css('.bd p::text').get().clean(),
"rating": card.css('.rating_num::text').get(),
# get("") 表示如果找不到 quote 元素,则返回默认值空字符串
"quote": card.css('.quote span::text').get(""),
}
# 2. 自动翻页逻辑:寻找"下一页"的链接
next_page = response.css('span.next a')
if next_page:
# 获取 href 属性并跟进请求
yield response.follow(next_page.first.attrib['href'])
# 3. 启动爬虫
if __name__ == "__main__":
result = MovieSpider().start()
print(f"爬取完成!共抓取到 {len(result.items)} 部电影。")
# 4. 一键导出为 JSON 文件
result.items.to_json("douban_movie.json", indent=True)
亮点解析:
- 异步并发 :得益于
async def和concurrent_requests,爬虫速度飞快。 - 数据清洗 :
get().clean()方法非常贴心,省去了手写strip()和正则替换的麻烦。 - 数据导出 :不需要手写
open(file, 'w')配合json.dump,result.items.to_json()一行代码直接搞定本地序列化存储。
四、 爬取成果展示 (douban_movie.json)
运行上述代码后,根目录下会自动生成一个 douban_movie.json 文件,数据格式非常规整:
[
{
"title": "肖申克的救赎",
"info": "导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...",
"rating": "9.7",
"quote": "希望让人自由。"
},
{
"title": "霸王别姬",
"info": "导演: 陈凯歌 Kaige Chen 主演: 张国荣 Leslie Cheung / 张丰毅 Fengyi Zha...",
"rating": "9.6",
"quote": "风华绝代。"
},
{
"title": "泰坦尼克号",
"info": "导演: 詹姆斯·卡梅隆 James Cameron 主演: 莱昂纳多·迪卡普里奥 Leonardo...",
"rating": "9.5",
"quote": "失去的才是永恒的。 "
}
// ... 此处省略后续 247 部电影数据 ...
]
五、 总结
通过这次 B 站实战教程的学习,我发现 Scrapling 很好地弥补了 requests 太单薄、Scrapy 太笨重的问题。它有着高度可读的 API、自带强大的防反爬工具箱、以及极其舒适的数据清洗/导出功能。
如果你也是爬虫学习者,强烈建议尝试一下这个框架!