You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Scrapy多用户登录批量数据提取并导出CSV?

实现Scrapy多用户批量登录与数据提取

针对你需要支持5000用户同时登录并导出数据的需求,我整理了一套修改方案,核心是让每个用户拥有独立的登录会话,同时优化并发控制和数据导出逻辑,避免冲突和反爬风险。

关键修改点说明

  • 用户列表管理:把硬编码的单用户改成从外部文件读取,方便维护大量用户
  • 独立会话隔离:通过Scrapy的meta传递每个用户的身份信息,确保每个请求都绑定对应的用户会话
  • 并发控制:调整Scrapy的设置参数,避免因请求量过大被目标网站封禁
  • 安全的CSV导出:使用Scrapy内置的Feed Exports替代手动文件写入,解决并发写入的冲突问题

步骤1:准备用户列表文件

创建users.csv,格式如下(每行一个用户的用户名和密码):

username,password
abc,xyz
user1,pass1
user2,pass2
...

步骤2:修改后的Scrapy Spider代码

import scrapy
import csv

class GiffgafSpider(scrapy.Spider):
    name = 'giffgaf'
    allowed_domains = ['www.something.com']
    login_url = 'https://www.something.com/auth/login'
    dashboard_url = 'https://www.giffgaff.com/dashboard'
    users_file = 'users.csv'

    def start_requests(self):
        # 读取用户列表
        with open(self.users_file, 'r') as f:
            reader = csv.DictReader(f)
            for user in reader:
                # 为每个用户发起登录页面请求,用用户名作为cookiejar标识隔离会话
                yield scrapy.Request(
                    self.login_url,
                    meta={'user': user, 'cookiejar': user['username']},
                    callback=self.parse_login_page
                )

    def parse_login_page(self, response):
        user = response.meta['user']
        # 提取登录表单的token
        token = response.xpath('.//*[@name="form_key"]/@value').extract_first()
        if not token:
            self.logger.error(f"Failed to get form token for user {user['username']}")
            return

        # 发起登录请求,携带用户信息和专属cookiejar
        yield scrapy.FormRequest(
            self.login_url,
            formdata={
                'form_key': token,
                'username': user['username'],
                'password': user['password']
            },
            meta={'user': user, 'cookiejar': response.meta['cookiejar']},
            callback=self.verify_login
        )

    def verify_login(self, response):
        user = response.meta['user']
        # 检查是否登录成功(根据目标网站实际提示调整判断逻辑)
        if "Invalid username or password" in response.text:
            self.logger.warning(f"Login failed for user {user['username']}")
            yield {'username': user['username'], 'password': user['password'], 'phone': 'Login failed', 'status': 'Failed'}
            return

        # 登录成功后请求仪表盘页面
        yield scrapy.Request(
            self.dashboard_url,
            meta={'user': user, 'cookiejar': response.meta['cookiejar']},
            callback=self.extract_data
        )

    def extract_data(self, response):
        user = response.meta['user']
        # 提取手机号,处理空值情况
        phonenumber = response.css("h2.profile-phone-number::text").get(default='N/A').strip()
        # 返回数据,交给Scrapy的Feed Exports统一处理
        yield {
            'username': user['username'],
            'password': user['password'],
            'phone_number': phonenumber,
            'status': 'Success'
        }

步骤3:配置Scrapy的Feed Exports(避免并发写入冲突)

在settings.py中添加以下配置,让Scrapy自动安全地导出CSV:

FEEDS = {
    'output.csv': {
        'format': 'csv',
        'fields': ['username', 'password', 'phone_number', 'status'],
        'overwrite': True,
        'encoding': 'utf-8',
    }
}

# 并发控制设置,根据目标网站反爬规则调整
CONCURRENT_REQUESTS = 16  # 同时处理的请求数,不要过高
DOWNLOAD_DELAY = 0.5  # 每个请求之间的延迟
COOKIES_ENABLED = True
COOKIES_DEBUG = False  # 关闭cookie调试,减少日志冗余

注意事项

  • 反爬应对:5000用户的请求量极大,建议分批次处理,比如每次处理100个用户,或者搭配代理IP池使用,避免被目标网站封禁
  • 错误处理:代码中加入了登录失败的判断逻辑,你可以根据目标网站的实际错误提示调整判断条件
  • 会话隔离:使用cookiejar参数为每个用户分配独立的cookie容器,确保用户之间的会话不互相干扰
  • 性能优化:如果用户量持续增加,可以考虑使用Scrapy-Redis分布式框架横向扩展爬虫能力

内容的提问来源于stack exchange,提问作者Riddi Kumar Shrestha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:52:17