尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python Scrapy实战:闲鱼二手商品数据爬取与解析

Python Scrapy实战:闲鱼二手商品数据爬取与解析 简介本资源是一套面向本科毕业设计与数据采集实践的Scrapy爬虫项目聚焦闲鱼平台二手商品信息的结构化抓取适用于Python网络爬虫初学者及毕业设计选题参考者。压缩包共11个文件含7个核心Python模块spiders、items、pipelines、middlewares、settings等构成完整Scrapy工程骨架、1份README说明文档、1个配置文件cfg、1个许可证License及1个.gitignore整体仅8KB轻量但结构规范便于快速部署与二次开发。已有145人学习下载体现了其在教学实践场景中的实用价值。读者可直接复用该工程框架掌握动态页面解析、反爬应对基础策略、数据管道清洗与存储流程并通过目录组织理解Scrapy标准项目分层逻辑为后续扩展代理池、分布式或可视化分析打下坚实基础。 做二手商品数据分析这个念头在我脑子里转了很久。起因特别朴素身边好几个朋友买卖二手手机、相机、游戏机的时候完全凭感觉定价要么挂高了无人问津要么卖低了心里滴血。我就想能不能抓一批闲鱼上的真实在售数据做一个价格区间参考。闲鱼是目前国内个人二手交易最活跃的平台天然是样本来源的首选。于是就有了这个基于 Python Scrapy 框架的闲鱼二手商品数据爬取项目最终整理成 zip 包发布方便拿到手直接部署。这篇文章我会把项目从零到一的完整过程写清楚为什么选 Scrapy、怎么搭工程、怎么处理闲鱼的登录态和反爬、怎么把数据落库以及实际踩过的那些坑。不管你是刚入门 Python 爬虫还是已经写过一堆脚本想往工程化方向走这篇都能给你一套可以直接上手的实施方案。1. 项目背景与整体设计思路1.1 为什么非要做这个项目很多人觉得二手平台数据没什么好爬的实际上价值比想象中大得多。闲鱼上的商品信息包含标题、价格、成色、卖家描述、发布时间、所在地区这些数据放到一起能分析出很多东西某个品类的主流成交价位、不同成色之间的价格差、热门商品的地域分布、卖家挂单的周期规律。对普通买家来说这些数据能告诉你现在入手会不会买贵对做二手回收、翻新、转卖的人来说这就是市场情报。我最早试过手动去搜一页一页翻复制粘贴。半小时才整理二十几条效率低到让人怀疑人生。后来想直接用 requests 写脚本但很快发现闲鱼的页面大量依赖异步接口普通 requests 拿不到什么有效内容而且各种参数校验、风控策略也让脚本频繁失效。这时候我才决定换 Scrapy因为它不只是一个简单的请求库而是一整套爬虫工程框架能让我把下载、解析、清洗、存储、统计这些环节全部串起来这个项目才算真正有了落地的可能。1.2 为什么是 Scrapy 而不是 requests 或 Selenium过去几年我写过不少爬虫最常用的套路无非三种。第一种是 requests BeautifulSoup适合结构简单的静态站点代码写起来很快但一旦遇到并发、重试、去重、分布式这类需求就得从头写一大堆轮子。第二种是 Selenium / Playwright适合重度动态渲染的页面但开浏览器跑脚本太吃资源并发一高机器就卡死而且效率通常比纯 HTTP 请求低一个数量级。第三种就是 Scrapy它把整个采集过程抽象成引擎、调度器、下载器、爬虫、管道五大组件异步并发是内置的中间件机制又让我可以在请求发出前和响应返回后做各种自定义处理。针对闲鱼这个目标Scrapy 的优势非常明显。闲鱼的数据请求量大需要高并发风控比较严格需要精细控制请求头、Cookie 和频次数据存储既要本地文件又要数据库Pipeline 机制可以直接分流。这些需求 Scrapy 天然都覆盖了。Selenium 我也试过但拿它跑了几百条数据后 CPU 直接拉满最后只是用来做登录态获取和个别动态区块的补充采集没有作为主采集手段。这是最合理的配置主链路用 Scrapy 走接口Selenium 只负责前期登录和疑难杂症的兜底。1.3 合规边界和平台规则说明聊爬虫之前必须先把合规这事说清楚。闲鱼官方没有对爬虫开放数据接口这套采集方案本质上是模拟用户行为去获取公开页面信息只适合个人学习研究、数据分析练习不能用于商业变现、批量倒卖数据、骚扰用户等任何违规场景。实际开发中我做了几件事来控制风险严格限制请求频率最大并发数设得比较低只采集商品公开信息不碰用户手机号、聊天记录、收货地址不对核心业务接口做压力测试拿到够用的样本就停。大家在复现的时候也一定要遵守这一点爬虫技术的价值在于提高效率而不是无节制地薅平台资源。另外强调一句我下面的代码示例都用了简化的选择器实际项目里不同时期的闲鱼页面结构可能会有变化你需要结合浏览器开发者工具实时调整。爬虫本身就是跟反爬体系动态博弈的过程没有一份代码能永远躺赚。2. 环境准备与 Scrapy 项目初始化2.1 环境依赖与安装这个项目基于 Python 3.9实测 3.10、3.11 都没问题。核心依赖只有几个不需要装一堆乱七八糟的库。下面是 requirements.txt 的内容我直接把版本参数标出来避免不同版本之间出现兼容性上的坑。scrapy2.11.2 pymysql1.1.1 pandas2.2.2 lxml5.2.2安装方式很简单pip install -r requirements.txt建议在 venv 虚拟环境里装别一上来就动全局环境。我见过太多人因为全局环境里各种包互相污染装了新版框架结果别的项目挂了最后只能重装系统才解决。虚拟环境的好处就是隔离这个项目坏了大不了删掉重建没有任何副作用。再补充一个细节Scrapy 装完之后在命令行输入 scrapy 如果提示找不到命令多半是 Python 的 Scripts 目录没有加到 PATH 环境变量。Windows 下直接去python -m pip install scrapy再python -m scrapy来验证或者把 Scripts 路径加进环境变量这是最常见的入门问题。2.2 创建项目骨架进入工作目录后用脚手架命令生成项目这个命令会一次性把目录结构、基础配置文件都建好省得自己手撸。scrapy startproject xianyu_spider cd xianyu_spider scrapy genspider xianyu www.goofish.com生成完的项目结构大致长下面这样xianyu_spider/ ├── scrapy.cfg └── xianyu_spider/ ├── __init__.py ├── items.py # 数据模型定义 ├── middlewares.py # 中间件UA、Cookie更新、重试 ├── pipelines.py # 管道数据清洗、去重、存储 ├── settings.py # 配置文件并发、延迟、管道开关 ├── spiders/ │ └── xianyu.py # 爬虫主逻辑 └── utils/ └── security.py # 我后来加的签名辅助模块可选这里有个很容易踩的坑scrapy startproject会生成一个跟项目名同名的包也就是内层那个 xianyu_spider 文件夹后面写所有代码都要进这个内层包。很多人分不清外层的 scrapy.cfg 和内层包的定位结果把配置文件改错位置半天跑不起来。2.3 settings.py 的关键参数配置settings.py 是 Scrapy 的灵魂项目能不能稳定跑一半看这里。我贴一份当前项目里最核心的配置并标注了每个参数背后的考虑。# settings.py 核心配置 BOT_NAME xianyu_spider SPIDER_MODULES [xianyu_spider.spiders] NEWSPIDER_MODULE xianyu_spider.spiders # 不遵守 robots.txt 的注释仅限个人学习严格受控场景 ROBOTSTXT_OBEY False # 并发与延迟宁可慢不可被封 CONCURRENT_REQUESTS 8 DOWNLOAD_DELAY 2 # 自动限速根据服务器响应时间动态调整 AUTOTHROTTLE_ENABLED True AUTOTHROTTLE_START_DELAY 3 AUTOTHROTTLE_MAX_DELAY 15 AUTOTHROTTLE_TARGET_CONCURRENCY 4 # 默认请求头 DEFAULT_REQUEST_HEADERS { Accept: application/json, text/plain, */*, Accept-Language: zh-CN,zh;q0.9, Referer: https://www.goofish.com/, User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36, } # 启用 Pipeline ITEM_PIPELINES { xianyu_spider.pipelines.XianyuPipeline: 300, xianyu_spider.pipelines.CsvPipeline: 400, xianyu_spider.pipelines.MysqlPipeline: 500, }AUTOTHROTTLE 这个东西很多人不太重视实际上是反封禁的一把好手。它会在爬虫运行过程中根据响应时延动态调整请求速度服务器响应一旦变慢它就自动降低并发和缩短请求频率相当于内置了一个自适应限速器。我实测下来开着它的效果比手动固定 DOWNLOAD_DELAY 要明显好尤其是长时间采集的时候被风控的概率能降很多。3. 爬虫核心实现与数据链路3.1 数据模型定义与字段设计写爬虫之前先把 Item 设计好。Item 相当于一张表的结构定义把所有需要采集的字段提前列好后面在 Spider 里填充在 Pipeline 里清洗在存储层落库全程都用同一个模型逻辑非常顺。我这个项目里最核心的字段是这些# items.py import scrapy class XianyuItem(scrapy.Item): keyword scrapy.Field() # 搜索关键词用于区分采集批次 title scrapy.Field() # 商品标题 price scrapy.Field() # 价格字符串转浮点数 original_price scrapy.Field() # 原价或划线价可能为空 city scrapy.Field() # 所在城市 seller_nick scrapy.Field() # 卖家昵称脱敏后 seller_credit scrapy.Field() # 卖家信用等级 item_url scrapy.Field() # 商品详情链接 publish_time scrapy.Field() # 发布时间 desc scrapy.Field() # 商品描述摘要 crawl_time scrapy.Field() # 抓取时间戳这里要给个建议字段越全越好但不要一开始就追求全。我第一版只设置了 title、price、url 三个字段发现数据落库后做分析时总缺东西又回去改代码重跑白白浪费时间。后来就吸取教训把涉及后续分析可能要用的字段一次性定义好宁可空着也别遗漏。3.2 Spider 主逻辑与搜索链接构造闲鱼的搜索其实有两种数据来源一种是网页端 HTML一种是移动端 JSON 接口。HTML 方案适合抓取单个商品详情页但搜索页本身经常是异步渲染直接拿 response.xpath 结果往往为空。JSON 接口方案更高效但需要处理签名参数和必要的 Cookie。两个方案我都在项目里实现了这里先讲相对通用的一种。# spiders/xianyu.py import json import scrapy from xianyu_spider.items import XianyuItem class XianyuSpider(scrapy.Spider): name xianyu def start_requests(self): keywords [iPhone 13, 索尼A7M3, Switch 续航版] for keyword in keywords: # 构造搜索接口的请求体具体参数名以抓包结果为准 form_data { keyword: keyword, page: 1, pageSize: 20, } yield scrapy.FormRequest( urlhttps://www.goofish.com/searchAPI, formdataform_data, cookiesself.settings.get(COOKIES), callbackself.parse_search, cb_kwargs{keyword: keyword}, ) def parse_search(self, response, keyword): data json.loads(response.text) items data.get(data, {}).get(items, []) for it in items: item XianyuItem() item[keyword] keyword item[title] it.get(title) item[price] it.get(price) item[city] it.get(city) item[seller_nick] it.get(sellerNick) item[item_url] it.get(itemUrl) item[crawl_time] scrapy.utils.project.crawler_time() yield item # 如需进一步抓取详情页可以再构造详情请求 detail_url https://www.goofish.com/item/%s % it.get(id) yield scrapy.Request( urldetail_url, cookiesself.settings.get(COOKIES), callbackself.parse_detail, cb_kwargs{item: item}, )这里的核心思路是先把请求参数写成可配置的字典方便后续更换关键词和分页。注意 FormRequest 和 Request 的区别闲鱼搜索接口明明是 POST如果你用 Request 发 GET基本会得到一个 403 或者参数错误。很多人第一次写这里就会卡住代码逻辑半天没发现问题结果只是请求方法不对。3.3 详情页解析与数据提取如果走 HTML 解析详情页我会用 XPath 进行提取。闲鱼详情页的结构在不同时期经常调整所以下面选择器只用于说明思路跑不起来的话一定要用开发者工具重新核对。def parse_detail(self, response, item): # 标题 title response.xpath(//h1[classtitle-text]/text()).get() # 价格 price response.xpath(//span[classprice-text]/text()).get() # 描述 desc response.xpath(//pre[classdesc-text]/text()).get() # 成色 quality response.xpath(//div[contains(class,quality)]/text()).get() if title: item[title] title.strip() if price: item[price] price.strip() if desc: item[desc] desc.strip() if quality: item[quality] quality.strip() yield itemXPath 解析有一个致命问题如果页面用了 JS 动态渲染HTML 里根本不会有这些文本而是藏在某个 JSON 变量里。遇到这种情况我通常用response.text全局搜索关键词比如搜title定位到包含商品信息的 JSON 块再用正则或者 json.loads 提取。这个技巧在动态页面里非常管用比选择器更稳。概括成一句话动态页面先找内嵌 JSON找不到再上无头浏览器。3.4 Pipeline 清洗与多端存储Pipeline 是 Scrapy 流程里我最喜欢的一个环节它让我可以在数据进入存储前做统一的清洗、去重、格式转换。比如价格字段接口返回的很可能是字符串带着¥符号或者1234.0这种格式必须在 Pipeline 里转成 float否则后续做分析时会炸。我的清洗管道是这样写的# pipelines.py import csv import pymysql class XianyuPipeline: def process_item(self, item, spider): # 价格清洗 if item.get(price): try: item[price] float(str(item[price]).replace(¥, ).strip()) except ValueError: item[price] None # 去除标题两端空白 if item.get(title): item[title] item[title].strip() # 简单去重标题为空的数据直接丢弃 if not item.get(title): raise DropItem(Empty title: %s % item) return item然后是 CSV 落盘。这里有一个容易被忽略的小细节用 open 写 CSV 时编码一定要用utf-8-sig而不是utf-8。因为 Excel 打开 UTF-8 编码的 CSV 时默认按 ANSI 解析中文会直接乱码加一个 BOM 头才能保证双击打开是正常的。这个坑我连续踩了两次才记住。class CsvPipeline: def __init__(self): self.file open(xianyu_data.csv, a, newline, encodingutf-8-sig) self.writer csv.DictWriter( self.file, fieldnames[keyword, title, price, city, seller_nick, item_url, crawl_time] ) self.writer.writeheader() def process_item(self, item, spider): self.writer.writerow(dict(item)) return itemMySQL 存储也是常规操作装个 pymysql 就行。注意数据库连接串里的字符集参数必须写成charsetutf8mb4否则遇到带 emoji 的商品标题、特殊符号写入会直接报错。闲鱼商品标题里 emoji 出现的概率非常高这一条基本是必备设置。class MysqlPipeline: def __init__(self, host, user, password, database, port3306): self.conn pymysql.connect( hosthost, useruser, passwordpassword, databasedatabase, portport, charsetutf8mb4, ) self.cursor self.conn.cursor() classmethod def from_crawler(cls, crawler): return cls( hostcrawler.settings.get(MYSQL_HOST), usercrawler.settings.get(MYSQL_USER), passwordcrawler.settings.get(MYSQL_PASSWORD), databasecrawler.settings.get(MYSQL_DATABASE), ) def process_item(self, item, spider): sql INSERT INTO xianyu_item (keyword, title, price, city, seller_nick, item_url, crawl_time) VALUES (%s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE priceVALUES(price) self.cursor.execute(sql, ( item.get(keyword), item.get(title), item.get(price), item.get(city), item.get(seller_nick), item.get(item_url), item.get(crawl_time), )) self.conn.commit() return itemON DUPLICATE KEY UPDATE 是一个很实用的小技巧配合 item_url 的唯一索引就能实现增量更新同一个商品再次抓到的时候不会重复插入而是只更新价格。这样你可以定期跑一次爬虫追踪商品价格随时间的变化这是二手交易分析里特别有价值的一个维度。4. 反爬应对与稳定性优化4.1 登录态、Cookie 与请求头管理闲鱼的数据接口对登录态要求很高匿名请求大概率拿不到数据。我试过直接在 requests 里带一个临时 Cookie能跑通一次但很快过期。后来验证出最稳定的方案是两步走先用 Playwright 打开一个真实的浏览器环境手动扫码登录闲鱼然后从浏览器上下文中导出 Cookie 字符串存到 Scrapy 项目的配置文件里。每隔一段时间重新导出一次即可。# 用 Playwright 导出现有 Cookie片段 from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessFalse) context browser.new_context() page context.new_page() page.goto(https://www.goofish.com/) input(扫码登录完成后回车继续...) cookies context.cookies() with open(cookies.json, w, encodingutf-8) as f: json.dump(cookies, f, ensure_asciiFalse) browser.close()然后把 cookies.json 里的内容转成 Scrapy 可用的字典格式写进 settings.py 或独立的 cookie 文件。在中间件里动态给每个请求挂上 Cookie比在每个 Request 里写死要省事得多。# middlewares.py class CookieMiddleware: def process_request(self, request, spider): cookie_str spider.settings.get(COOKIE_STRING) if cookie_str: request.headers[Cookie] cookie_str注意 Cookie 字符串里包含了很多敏感字段不要提交到公开代码仓库。我在 zip 包里会放一个cookie.example.json真正的 Cookie 文件放在本地并写进 .gitignore。爬虫项目最忌讳的就是把个人 Cookie 泄漏到公开网络这个风险需要从一开始就防住。4.2 动态接口与防检测策略闲鱼的反爬不只靠 Cookie还有请求签名和风控参数。直接照着网页请求复制出来没加密参数过不了多久就会返回一段 JS 验证代码。这个时候你可以做几件事第一降低请求频率这个是最有效但很多人不愿意做的第二保证请求头完整尤其重点检查 Referer、Accept、Accept-Language 这三个字段少了任何一个都容易被标记第三用中间件定期更换 User-Agent不要所有请求都用同一个 UA浏览器指纹相似的请求聚集在一起风控系统会格外关注。我项目里的 User-Agent 中间件维护了一个常见 UA 列表每次请求从中随机取一个import random class RandomUserAgentMiddleware: UA_LIST [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/125.0, ] def process_request(self, request, spider): request.headers[User-Agent] random.choice(self.UA_LIST)需要说明的是UA 随机化只是基础手段主要目标是让请求更像真实浏览器而不是为了绕过什么高级风控。真正科学的态度是默认做良性采集用合理的频率访问公开数据这样既对平台友好也不会给自己惹麻烦。4.3 限速、去重与失败重试机制Scrapy 默认的去重是基于 request URL 的。对于搜索接口URL 上带了分页参数天然不会重复但对于详情页 URL如果搜索结果里有同一商品多次出现可以用Request(..., dont_filterTrue)或者依赖 Pipeline 去重。我个人更倾向在 Pipeline 里维护一个 title item_url 的哈希集合达到内存去重和数据库去重双重保险。失败重试同样很重要。二手平台的接口时不时就超时或返回 5xx如果不做重试数据就是一漏一大片。settings.py 里我开了RETRY_ENABLED True RETRY_TIMES 3 RETRY_HTTP_CODES [403, 408, 500, 502, 503]注意 403 不一定是网络问题也可能是 Cookie 失效或触发了风控。如果重试三次还是 403建议先停下来检查 Cookie而不是一味提高重试次数。这个经验我特意写在代码注释里防止后来接手的人看着日志以为只是偶发故障。还有一个很多人忽略的点DOWNLOAD_DELAY 和 AUTOTHROTTLE 不要同时冲突。你可以先关掉 AUTOTHROTTLE用固定 DOWNLOAD_DELAY 跑小批量数据感受一下速度觉得稳定后再开自适应限速跑大批量。上来就全部开启参数叠加可能导致请求效率极低几千条数据要跑十几个小时。5. 常见问题与排查技巧实录5.1 我踩过的几个典型坑第一个坑是中文乱码。第一次跑通爬虫打开 CSV 发现所有中文全是乱码当时还以为是数据源的问题折腾半天才意识到是编码。后来统一用 utf-8-sig 写文件这个问题再没出现过。第二个坑是字段全部为空。搜索接口返回的数据结构跟我想象的完全不一样我以为在 JSON 顶层就有 title、price结果是套了两层嵌套还有一个 data 数组。当时调试的时候我用的方法很简单先把整个响应打印出来肉眼扫一遍找到 title 在什么位置再看看它周边的字段是什么。这个方法虽然原始但往往比猜选择器快得多。很多人习惯直接套网上模板不打印实际响应结果页面一改就彻底抓瞎。第三个坑是被风控拦截后全局 403。当时我没看日志只是一直重试结果把请求频率顶得越来越高最后整个 IP 被临时限制访问连浏览器都打不开闲鱼了。后来我做了两件事一是强制把并发调低到 4延迟设置成 3 秒以上二是加了一个熔断机制——如果连续 10 个请求都返回 403中间件就主动让爬虫休眠 60 秒再继续。这个机制很朴素但非常管用属于用时间换稳定性的经典思路。5.2 问题速查表问题现象可能原因排查与解决思路返回 403Cookie 失效、请求头不完整更新 Cookie检查 Referer 和 UA 字段搜索页无数据接口是动态渲染HTML 里没有内容抓包找真实接口或解析页面内嵌 JSON数据全部为 None字段路径错误、签名参数缺失打印实际响应对照开发者工具逐层核对中文乱码CSV 编码问题写入用 utf-8-sig请求完成后设置 response.encoding utf-8价格字段报错字符串带符号或为 None在 Pipeline 里统一 try/except 转换跑到一半全部超时并发过高或触发限流调低 CONCURRENT_REQUESTS开启 AUTOTHROTTLE数据库写入 emoji 报错连接字符集不是 utf8mb4设置 charsetutf8mb4并确认表结构也是 utf8mb4Selenium 配合时内存暴涨浏览器实例未关闭用 context manager 或 finally 确保 browser.close()5.3 稳定性调优与长期运行建议如果你只是跑一次拿样本数据那前面的内容基本够用了。但如果你打算每周跑一次长期追踪价格变化我建议在项目里再加几个东西。一个是数据分目录存储。把每天的采集结果按日期存放比如data/2025-06-01.csv、data/2025-06-08.csv后续做时间序列分析会非常方便也不用担心单文件越滚越大。另一个是日志分级。Scrapy 默认的日志在控制台刷屏根本没法定位问题。我在 settings.py 里把日志写到了文件并设置了不同的日志级别LOG_ENABLED True LOG_LEVEL INFO LOG_FILE scrapy.log这样每次跑完直接翻开日志文件就能看到有多少条请求、多少条成功、多少条失败、失败原因是什么。特别是夜里挂着爬虫第二天早上第一件事就是看日志而不是看控制台有没有被系统清掉。还有一个进阶思路是做关键词轮换。不要长时间用同一个关键词反复搜索可以在一个爬虫任务里维护一组关键词队列每跑完一个就换下一个。这样做有两个好处一是数据覆盖面更广二是避免因为对单一关键词高频搜索触发风控。我这个项目后续就是从 3 个关键词扩展到 30 个跑一整夜能拿到几万条数据已经足够支撑一份像样的分析报告了。6. 从 zip 下载到一键运行的快速上手6.1 项目压缩包目录说明整个项目打成 zip 后里面有这些核心文件xianyu_spider.zip ├── xianyu_spider/ │ ├── scrapy.cfg │ ├── requirements.txt │ ├── README.md │ └── xianyu_spider/ │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders/ │ └── xianyu.py ├── cookie.example.json └── run.pyrun.py 是我额外写的一个启动脚本作用是把环境检查、Cookie 加载、爬虫启动这几个步骤串起来避免每个人都要手动敲一堆命令。如果你拿到 zip 包后不想看文档直接按顺序执行下面几步就能跑起来。6.2 从零启动的完整命令流程# 1. 解压 unzip xianyu_spider.zip cd xianyu_spider # 2. 创建虚拟环境并安装依赖 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt # 3. 准备 Cookie # 把 cookie.example.json 复制成 cookie.json并按 README 里的方式填入真实 Cookie # 4. 启动爬虫 python run.py如果你想直接控制输出文件位置也可以在项目根目录执行scrapy crawl xianyu -a keywordiPhone -a max_pages5把关键词和页数作为运行时参数传进去可以灵活调整每次采集的范围。这个功能在代码里是通过__init__方法接收命令行参数实现的大家看代码的时候会注意到。6.3 二次开发建议拿到 zip 包以后建议先别急着跑花十分钟把代码读一遍重点关注 settings.py 里的并发参数和 Cookie 配置。第一次跑的时候一定要从小批量开始比如先只爬一个关键词的前两页确认数据能正常落库再逐步增加关键词和页数。直接上来就全量跑大概率会遇到各种预期外的错误反而拖慢进度。如果想要扩展可以考虑加一个定时调度模块让爬虫每隔几天自动运行一次也可以加一个简单的可视化页面把价格分布以图表形式展示出来。基础数据链路我们已经搭好了后面的方向几乎是想怎么玩就怎么玩。在写这个项目的时候我最深的体会是爬虫最大的成本不是写代码而是跟不断变化的页面结构和风控策略周旋。今天还在用的选择器明天可能就失效今天的接口参数后天可能就加了签名。所以这个项目里我尽可能把容易变化的部分都抽成了配置和辅助函数让后续维护的人不用改主逻辑也能继续跑。另外我也真心建议大家做数据采集的时候永远记住分寸两个字把频率控制在合理范围内把用途限制在学习与个人分析上这套技术才能真正发挥价值。本文还有配套的精品资源点击获取
返回列表