文章目录
(示意图:Scrapy框架架构流程图)
开篇先扔个测试用例感受下(新手可以跳过直接看正文):
class TestSpider(scrapy.Spider):
name = "test"
start_urls = ['https://quotes.toscrape.com']
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').get(),
'author': quote.xpath('span/small/text()').get()
}
一、为什么Scrapy值得你投入时间?
1.1 那些年我们踩过的爬虫坑
试过用Requests+BeautifulSoup写爬虫的程序员都知道(说多了都是泪):
- 遇到分页就抓瞎,得自己写循环
- 反爬稍微升级就得连夜改代码
- 数据量大时就卡成PPT
- 数据存储要手动处理格式…
1.2 Scrapy的降维打击
这货直接给你全自动流水线作业!举个真实案例:某电商平台百万级商品数据抓取,用原生脚本需要200行代码+3小时运行,改用Scrapy后代码量减少60%,效率提升5倍!
二、环境搭建(3分钟极速版)
2.1 安装的正确姿势
# 强烈建议用虚拟环境!!!
python -m venv scrapy_env
source scrapy_env/bin/activate # Linux/macOS
scrapy_env\Scripts\activate # Windows
pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple
2.2 创建第一个项目
scrapy startproject myproject
cd myproject
scrapy genspider demo_spider example.com
项目结构详解(重点标记):
myproject/
├── scrapy.cfg # 部署配置文件
└── myproject/
├── __init__.py
├── items.py # 数据结构定义
├── middlewares.py # 中间件配置(核心!)
├── pipelines.py # 数据处理管道
├── settings.py # 全局设置(必改项)
└── spiders/ # 爬虫目录
└── demo_spider.py
三、核心组件揭秘(手把手教学)
3.1 Spider的十八般武艺
class ArticleSpider(scrapy.Spider):
name = "article_spider"
# 启动种子(两种方式任选)
start_urls = [
'https://news.site/page1',
'https://news.site/page2'
]
# 或者用start_requests更灵活
def start_requests(self):
urls = [...] # 动态生成URL
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
# CSS选择器实战
titles = response.css('h1.article-title::text').getall()
# XPath高级用法
dates = response.xpath('//div[@class="meta"]/span[1]/text()').get()
# 混合使用更强大
for article in response.css('div.article'):
yield {
'title': article.xpath('.//h2/text()').get(),
'author': article.css('p.author::text').get(),
'content': article.xpath('.//div[@class="content"]//text()').getall()
}
# 自动翻页黑科技
next_page = response.css('a.next-page::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
3.2 Item Pipeline数据流水线
创建一个完整的处理流程:
# pipelines.py
class MyprojectPipeline:
def process_item(self, item, spider):
# 数据清洗
item['title'] = item['title'].strip()
# 去重处理
if self.is_duplicate(item):
raise DropItem("Duplicate item found")
return item
class MongoDBPipeline:
def open_spider(self, spider):
self.client = pymongo.MongoClient()
self.db = self.client['mydatabase']
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
self.db[spider.name].insert_one(dict(item))
return item
四、突破反爬的七大绝招(价值连城!)
4.1 伪装大法
# settings.py
DOWNLOAD_DELAY = 2 # 下载延迟(秒)
CONCURRENT_REQUESTS = 16 # 并发请求数
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...'
# middlewares.py
class RandomUserAgentMiddleware:
def process_request(self, request, spider):
request.headers['User-Agent'] = random.choice(USER_AGENTS)
4.2 代理IP池
PROXY_LIST = ['http://ip1:port', 'http://ip2:port']
class ProxyMiddleware:
def process_request(self, request, spider):
proxy = random.choice(PROXY_LIST)
request.meta['proxy'] = proxy
五、实战:豆瓣电影TOP250抓取
完整代码示例:
class DoubanSpider(scrapy.Spider):
name = "douban_movie"
start_urls = [f'https://movie.douban.com/top250?start={i*25}' for i in range(10)]
def parse(self, response):
for movie in response.css('div.item'):
yield {
'title': movie.css('span.title::text').get(),
'rating': movie.css('span.rating_num::text').get(),
'quote': movie.xpath('.//span[@class="inq"]/text()').get(),
'link': movie.css('div.hd > a::attr(href)').get()
}
六、常见问题急救包
6.1 遇到403/被封IP怎么办?
- 开启Rotating Proxies
- 随机化请求头
- 启用Cookies中间件
- 设置DOWNLOAD_DELAY
6.2 动态加载内容处理
使用Selenium中间件:
from scrapy_selenium import SeleniumRequest
yield SeleniumRequest(
url=url,
callback=self.parse_result,
wait_time=3,
script='window.scrollTo(0, document.body.scrollHeight);'
)
七、性能优化技巧(压箱底干货)
- 启用缓存:
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 3600
- 启用异步处理:
CONCURRENT_REQUESTS = 100
REACTOR_THREADPOOL_MAXSIZE = 20
- 使用文件管道批量存储:
ITEM_PIPELINES = {
'scrapy.pipelines.files.FilesPipeline': 1
}
FILES_STORE = '/path/to/dir'
写在最后
Scrapy的学习曲线看起来陡峭(其实真的不难!),但只要掌握核心组件和运行机制,剩下的就是按需求组装各种中间件和管道。记住几个关键点:
- Middleware是灵魂:所有高级功能都要从这里入手
- Pipeline是武器库:根据业务需求自定义数据处理方式
- Settings是调节器:不同场景要灵活调整参数组合
最后送大家一个私藏技巧:多用scrapy shell <url>
调试选择器,效率直接翻倍!遇到问题欢迎评论区交流,看到必回~