06年老电脑装Ubuntu 14.04跑Python爬虫与自动化脚本实战
发布时间:2026/10/6 22:49:11 作者:尧图编辑部 阅读量:1,286

08年的时候我攒下人生第一台电脑奔腾D双核、512MB内存、80G串口硬盘放到今天连打开网页都费劲。但最近公司机房清理我把它捡了回来——不是情怀是我突然觉得这种配置装个Ubuntu 14.04跑Python爬虫和自动化脚本其实绰绰有余。折腾了一个周末这台06年的老爷机重新亮了起来作为一台24小时值守的内网采集机每天定时跑任务、自动抓页面、把结果整理成报表稳定运行到现在。这篇文章就是完整复盘从系统选型、装机瘦身到编译新版Python再到爬虫和自动化脚本落地最后讲清楚怎么让它长期稳定挂着当“守门员”。内容偏向实操全程我用的是这台06年机器的真实环境每个命令都跑过每个坑都踩过看完你也能复现。1. 为什么是Ubuntu 14.04老硬件面前的选择题1.1 06年电脑的典型配置基准动手之前先摸清底子。06年左右的品牌台式机配置大致在这样一个档位部件常见配置影响CPU奔腾D 820/830、赛扬D、少量酷睿2双核但频率低单核性能甚至不如现在手机内存512MB DDR2 或 1GB DDR2最大的瓶颈容易爆内存硬盘80G~160G SATA 机械盘速度慢随机读写是噩梦显卡集成显卡/低端独显2D够用3D别想网络百兆网卡现在看是瓶颈跑爬虫够我拿到的这台是奔腾D 820、1GB内存、160G硬盘属于这批机器里偏好的。如果你手里是512MB内存下面所有方案依然适用只是桌面能少装的尽量少装。1.2 候选系统挨个过一遍把这台机器的定位想清楚很重要它不是拿来当主力工作机而是当一个“轻量级值守盒子”——跑爬虫、定时任务、偶尔被SSH登录检查一下。基于这个定位系统选择逻辑完全变了。Windows XP微软早已终止支持以太网驱动、USB驱动得翻老光盘而且XP跑Python 3.6很费劲更别说之后我们还要编译新版Python身份验证和安全补丁都是问题。直接pass。Windows 71GB内存跑Win7基本是幻灯片装完系统就得占700MB左右真正留给Python的内存少得可怜换2G内存虽然便宜但到手也得时间先不考虑。新版Ubuntu16.04及以上2016年以后的内核和systemd确实很成熟但Unity/GNOME桌面以及在线升级机制对06年CPU不友好。1GB内存装Ubuntu 20.04桌面版开机CPU占用能飙到90%以上基本没法用。Ubuntu 14.04Trusty Tahr2014年发布内核3.13带PAE支持对这类老CPU非常友好。默认Unity桌面虽然也卡但我们装的时候直接选择安装openbox/LXDE/XFCE桌面内存占用能压到250MB左右给Python留出大量余量。更重要的是14.04保留了传统的sysvinit/upstart启动方式系统服务管理逻辑简单非常适合无人值守。Lubuntu/Gentoo/Arch等其他发行版Lubuntu 14.04其实也可以但既然你想基于Ubuntu生态我会以Ubuntu 14.04为主线来写桌面换成LXDELubuntu桌面环境或XFCE都行本质一样。结论一句话Ubuntu 14.04不是性能最好的选项但它是兼容性、软件生态、社区资料“三合一”的最优解。所有老驱动在14.04里都有甚至不用找一个设备的驱动光盘。1.3 EOL系统的安全性怎么看必须坦白14.04在2019年就正式停止官方维护了软件源默认会被挪到old-releases没有任何安全补丁流入。但我们这台机器定位是内网专用、不直接暴露公网而且跑的是定时采集任务不开放外部端口威胁面可控。如果你的机器要暴露到公网我不建议用EOL系统。实际操作中我把这台机器放在了办公网内网段通过SSH管理Web面板也只监听局域网地址192.168.x.x安全策略就是“能不出网就不出网”。爬虫要访问外网时限制频率避免成为某个网站的负担也不去碰任何需要登录授权的敏感接口。2. 装机实战从U盘启动到基础系统瘦身2.1 老机器怎么引导安装06年的机器很多不支持U盘启动或者BIOS里的USB-HDD选项很挑剔。我遇到的情况是U盘启动选项能识别但进不去引导界面最后老老实实刻了一张CD用光驱装。如果你有光驱和闲置光盘这是最省事的路。下载Ubuntu 14.04.5 desktop i386镜像选i386而不是amd64原因有二1GB内存下32位系统占用更低老CPU虽然支持64位指令集但跑32位省内存更明显200多MB。用刻录软件烧录到光盘。开机按Del或F2进BIOS把第一启动项改成光驱。插入光盘保存重启进入安装界面选“Install Ubuntu”一路下一步就行。如果你确定U盘能引导可以用Rufus或Universal USB Installer写盘然后在BIOS里把第一启动项设为USB-HDD同时关闭软驱Floppy这两个细节没处理会卡在“Boot error”或“GRUB”提示。2.2 安装器的两个经典坑A. 内存不足告警512MB内存用Desktop版安装器很容易直接卡在“Your computer has low memory”或者图形界面起不来。解决办法是安装启动时按F6在启动参数里加mem512m限制内核可见内存或者直接用Server版ISO安装——Server版是字符界面对内存要求低很多。装好基本系统后再手动装桌面环境这一步对老机器来说反而更高效。安全起见我直接建议用Server版ISO装命令行系统装完再按需装桌面。我们的核心任务是Python爬虫和自动化桌面只做调试用Serer版反而把多余组件全部省略。B. 分区卡住安装器默认使用整个磁盘但对这种老爷机我建议手动分区布局如下分区大小挂载点文件系统说明/dev/sda11G/bootext4内核文件独立放避免主分区满/dev/sda21Gswapswap交换分区内存太小时救急/dev/sda3剩余/ext4系统Python脚本注意两点老机械硬盘的swap一旦内存告急疯狂交换整个系统会卡到怀疑人生。所以我推荐把swap设置成1G——可以没有但不能大后面我们还有zRAM方案替代传统swap到时候swap分区基本用不上。另外/boot独立放1G是因为老BIOS有时在引导时对大分区敏感单独分一个小boot分区可以避免很多引导问题。2.3 装完必做的五件事系统装好后不要急着配Python先把基础环境清理干净换源14.04官方源在EOL之后默认指向old-releases.ubuntu.com装机时如果没有自动配置你会看到apt-get update报一堆404错误。我直接手工指过去sudo sed -i s/archive.ubuntu.com/old-releases.ubuntu.com/g /etc/apt/sources.list sudo sed -i s/security.ubuntu.com/old-releases.ubuntu.com/g /etc/apt/sources.list sudo apt-get update这里有个重要坑即使换了源apt-get update也可能报“Release file expired”的错误。因为Ubuntu仓库的Release文件带Valid-Until字段文件过期后apt默认拒绝使用。解决办法是加上忽略有效期参数sudo apt-get -o Acquire::Check-Valid-Untilfalse update后面每次apt-get update都建议带上这个参数不然随时给你脸色看。国内用户如果想加速可以把old-releases.ubuntu.com替换成你本地的旧版镜像地址原理一样。装openssh-server值守机必须有SSH。sudo apt-get install openssh-server换轻量内存桌面如果是Server版装的我们只装一个非常轻量的窗口管理器比如LXDE。不需要完整安装lubuntu-desktop那个巨无霸单独装LXDE核心即可sudo apt-get install lxde-core xinit重启后登录界面选择LXDE会话。如果连LXDE都觉得多余还可以直接装Openbox裸窗口但一般没必要。关闭用不上的服务打印机服务cups、蓝牙服务bluetooth、崩溃报告whoopsie按需关掉sudo update-rc.d cups disable sudo update-rc.d bluetooth disable sudo update-rc.d whoopsie disable这步能省几十MB内存对1GB机器很可观。注意update-rc.d是sysvinit时代的命令在14.04上还能用不要用systemctl。安装常用工具链sudo apt-get install git vim curl wget htop build-essential libssl-dev libffi-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-devbuild-essential里的gcc 4.8是老系统默认编译器后面编译Python靠它。libssl-dev的坑下面单独讲。2.4 镜像源失效后的故障排查闭环如果你没有换源或者换了之后依然有报错先用apt-get update看完整错误常见三种报错特征直接原因处理404 Not Found源地址指向了已归档版本换到old-releases或对应镜像Release file expiredRelease文件有效期过了加-o Acquire::Check-Valid-UntilfalseCould not resolve网络不通/DNS问题ping一下源域名确认网关排查思路就三步一看源地址是否有效二看是否忽略有效期三看网络是否通。这比盲目重装系统强得多。3. 给14.04装现代Python编译这条路3.1 系统自带Python为什么不行Ubuntu 14.04自带Python 2.7.6和Python 3.4.3。Python 2确实老了3.4.3在2023年的爬虫生态里也基本被所有现代库抛弃——requests新版本要Python 3.7lxml新版也要3.8Flask 3.x更是要求3.8及以上。装老版本库倒是能跑但老版本库通常带着一堆安全漏洞和兼容性问题还很多坑。既然要跑爬虫和自动化不如直接装一个3.9.18平衡兼容性和现代性。为什么是3.9而不是3.123.12可以编译但对老机器的优化方向不同而且3.9系列是“最后一拨对老旧Linux系统兼容特别友好的版本”3.9在requests/lxml/flask生态里完美适配不用装一堆补丁更重要的是3.9对CPU编译优化不强制开启PGO老机器编译时间可控。3.2 先绕过一个天坑OpenSSL14.04自带的OpenSSL是1.0.1f这个版本太老Python 3.9在配置时如果链接到系统OpenSSL会出现大量SSL警告pip走HTTPS下载包时会直接报错。这不是pip源的问题是底层SSL库兼容性问题。我当时查了很多资料最稳妥的办法是单独编译一份新版OpenSSL并让Python链接过去。# 下载OpenSSL 1.1.1系列最后一个带长期维护的版本 wget https://www.openssl.org/source/openssl-1.1.1v.tar.gz tar xzf openssl-1.1.1v.tar.gz cd openssl-1.1.1v # 编译安装到/opt/openssl ./config --prefix/opt/openssl --openssldir/opt/openssl make -j2 sudo make install如果下载环节过不去可以用curl -O或者国内镜像站下载反正拿到源码包就行。编译OpenSSL在老CPU上大约20~40分钟可以泡杯咖啡等。3.3 编译安装Python 3.9.18拿到Python源码wget https://www.python.org/ftp/python/3.9.18/Python-3.9.18.tar.xz tar xJf Python-3.9.18.tar.xz cd Python-3.9.18配置时指定我们刚编译的OpenSSL并关闭PGO优化./configure --prefix/usr/local/python3.9 --with-openssl/opt/openssl --enable-optimizationsno为什么不开--enable-optimizations这个参数会跑PGOProfile Guided Optimization需要先用系统Python编译一遍、跑测试、再编译第二遍。老CPU上整套流程奔着五六个小时去了对爬虫任务没有明显收益。不做PGO的普通编译同样好用机器会节省大量时间。make -j2 sudo make install-j2对应双核CPU如果CPU是单核就只写make不加-j参数。整个编译过程大约2小时过了开头最焦躁的半小时后面基本就是“等”。编译过程中如果报缺什么头文件回头在1.3节命令里补装对应-dev包再重跑make。验证是否成功/usr/local/python3.9/bin/python3.9 --version /usr/local/python3.9/bin/python3.9 -c import ssl; print(ssl.OPENSSL_VERSION)如果输出OpenSSL 1.1.1v之类的字样说明SSL链接成功如果显示的是系统老的1.0.1f说明--with-openssl没生效检查config时是否报错。3.4 pip源、venv和第一个虚拟环境源码编译的Python自带ensurepip和venv模块直接建虚拟环境绝不往系统全局pip里装东西——老系统全局pip装了新库容易污染系统Pythonsudo /usr/local/python3.9/bin/python3.9 -m ensurepip /usr/local/python3.9/bin/python3.9 -m venv /home/ubuntu/venvs/spider然后配置pip源国内网络环境直接指向清华或阿里镜像速度差很多cat /home/ubuntu/venvs/spider/pip.conf EOF [global] index-url https://mirrors.aliyun.com/pypi/simple/ trusted-host mirrors.aliyun.com EOF用虚拟环境里的pip装第一波依赖sudo apt-get install libxml2-dev libxslt1-dev /home/ubuntu/venvs/spider/bin/pip install requests lxml flask这里为什么要先装libxml2-dev libxslt1-dev因为没有它们pip install lxml会走“源码编译附带libxml2”的老路在老CPU上编译Libxml2至少多等半小时而且容易因系统组件太老编译失败。装了dev包之后lxml直接用系统库绑定几分钟装完。3.5 编译过程时间预期与能耗参考对这台06年双核奔腾D分步计时大概是步骤时间编译OpenSSL20~40分钟编译Python不开PGO1.5~2小时pip安装requests/lxml/flask5~15分钟如果中途编译失败Append日志再查90%的情况是缺某个-dev包补齐然后重跑make即可不用从头开始。4. 爬虫与自动化脚本落地4.1 老机器爬虫选型为什么不用Selenium看到爬虫两个字很多人第一反应是Selenium或Playwright开个浏览器去“真实模拟”。但在这台机器上我一开始也试过Selenium——结论是放弃。原因很直接1GB内存跑Chrome/Firefox Selenium Driver内存直接飙到900MB系统卡死14.04的老Firefox和一个Chromium衍生版本驱动匹配极其麻烦找geckodriver/chromedriver的老版本本身就是个大坑Selenium的本质是模拟浏览器交互老CPU跑每步操作都慢得像幻灯片。替代方案是requests lxml/xpath。绝大多数能爬的公开页面不需要渲染JavaScript直接抓HTML然后XPath提取就行。如果需要登录后才能看的页面也可以用requests的Session维持Cookie模拟表单提交比浏览器轻几个数量级。只有当页面是纯JS渲染、内容完全没有静态HTML时我们才考虑浏览器方案但06年机器上这种需求我选择直接放弃。4.2 一个能跑的通用的采集示例以大而化之的场景为例每天定时抓取某个公开新闻站的标题列表存成文本作为日报。目录结构如下/home/ubuntu/ ├── venvs/ │ └── spider/ ├── jobs/ │ ├── daily.py │ └── report.py ├── logs/ │ └── daily.log └── webui.pyjobs/daily.py核心代码#!/home/ubuntu/venvs/spider/bin/python3.9 import requests import time from lxml import html from datetime import datetime # 目标公开页面请换成你有权限访问或对方明确允许爬取的页面 url https://example.com/news headers { User-Agent: Mozilla/5.0 (compatible; ResearchBot/1.0; http://example.com/bot), Referer: https://example.com } def fetch_titles(): resp requests.get(url, headersheaders, timeout15) resp.raise_for_status() doc html.fromstring(resp.content) titles doc.xpath(//h2/a/text() | //h3/a/text()) return [t.strip() for t in titles if t.strip()][:20] def main(): try: titles fetch_titles() if not titles: return 无数据 out /home/ubuntu/logs/report.txt with open(out, a) as f: f.write(f\n[{datetime.now():%Y-%m-%d %H:%M}]\n) for idx, title in enumerate(titles, 1): f.write(f{idx}. {title}\n) print(titles[:5]) except Exception as e: print(fERROR: {e}) if __name__ __main__: main() time.sleep(2) # 礼貌限速几点说明User-Agent里写清是bot并附上园子说明这是一种遵守robots精神的礼貌做法别伪装成真人刷来刷去time.sleep(2)是底线单次采集任务结束后至少等两秒再结束避免对目标站造成压力采集前先看一眼目标站的robots.txt如果明确写了Disallow /那就别硬爬如果网站提供了RSS或官方API优先用raise_for_status()让HTTP错误直接抛异常方便排查。4.3 自动化第二步表单提交模拟爬虫之后是自动化。老机器上最实际的自动化就是模拟登录、打卡、填表这类轻操作。思路是用requests.Session()保持Cookie模拟浏览器提交表单。import requests s requests.Session() # 第一步GET登录页提取CSRF token或hidden input login_page s.get(https://example.com/login, timeout10) # 找到token不同站逻辑不同一般用lxml配合xpath取值 token 从页面HTML中解析出的token值 login_data { username: your_user, password: your_pass, csrf_token: token, submit: login, } r s.post(https://example.com/login, datalogin_data, timeout10) r.raise_for_status() # 登录成功后用同一个session访问需要认证的页面 resp s.get(https://example.com/dashboard, timeout10)这里有个很关键的坑很多站的登录页会隐藏一个csrfmiddlewaretoken直接POST静态表单不带上它会被拒。用XPath把它挖出来再拼进请求体是这类自动化的基本操作。如果不确定具体参数名用Chrome/Firefox的开发者工具手动抓一次登录请求照着字段复制成dict即可。安全红线只能对自己有权限的系统、或者对方明确允许自动化访问的服务做这种模拟。拿别人的登录页试脚本既违反网站条款也可能触犯法律。如果你要做的自动化对象是你自己的账号问题不大如果是别人的系统先取得授权。4.4 定时驱动用cron还是用systemd timer14.04默认装的是cron直接用。crontab -e写入# 每天7点30分跑采集任务 30 7 * * * /home/ubuntu/venvs/spider/bin/python /home/ubuntu/jobs/daily.py /home/ubuntu/logs/daily.log 21 # 每隔30分钟检查一次服务状态 */30 * * * * echo alive /home/ubuntu/logs/alive.log两个坑记得写MAILTO不写的话每次cron任务输出都会发一封邮件到系统邮箱积累几十封空邮件后磁盘会涨起来。cron环境变量和登录shell不一样。cron执行时PATH只有/usr/bin:/bin绝对路径一定写全。使用虚拟环境Python时直接call全路径/home/ubuntu/venvs/spider/bin/python不要用python简写。4.5 Flask微型面板采集到的结果挂在文本里每次SSH进来看不方便。我在同一台机器上用Flask写了个微型Web面板局域网内用浏览器打开就能看每天的采集结果。整个程序不超过30行from flask import Flask, render_template_string, send_file import glob import os app Flask(__name__) LOG_DIR /home/ubuntu/logs app.route(/) def index(): files sorted(glob.glob(os.path.join(LOG_DIR, *.txt)), reverseTrue)[:5] data [] for f in files: with open(f) as fh: lines fh.read().splitlines() data.append((os.path.basename(f), len(lines), lines[:30])) return render_template_string( h1采集结果/h1 {% for name, count, lines in data %} h2{{ name }} ({{ count }}条)/h2 pre{{ lines | join(\n) }}/pre {% endfor %} , datadata) app.route(/report) def report(): return send_file(os.path.join(LOG_DIR, report.txt)) if __name__ __main__: app.run(host0.0.0.0, port8080)启动方式nohup /home/ubuntu/venvs/spider/bin/python /home/ubuntu/webui.py /tmp/webui.log 21 然后局域网内访问http://192.168.x.x:8080就能看结果。如果只是内网访问不需要反向代理和域名直接Flask跑裸端口就够了。4.6 xpath解析的常见翻车点XPath在爬虫里是高频操作老机器上调xpath容易踩的两个坑一是text()只取直系文本。比如//h2/a/text()如果a标签里有嵌套spantext()取不到span里的内容。正确的拿法是//h2/a//text()获取当前节点下所有文本子节点的数组再用.join(...)拼接。二是href与text错位。只要同时拿标题和链接建议用zipitems doc.xpath(//h2/a[href]) for a in items: title .join(a.xpath(.//text())) href a.get(href)如果直接一次性doc.xpath(//h2/a/text())和doc.xpath(//h2/a/href)各自提取再想一一对应遇到页面里某个标题没有链接或有多余子节点时就会对不上。这是老手新手都常犯的错我在这个坑上浪费过半小时。5. 让老电脑7x24值守运维与稳定5.1 SSH免密登录老机器放墙角没有屏幕键盘每次调试都靠SSH。免密登录省去输密码的重复操作# 在本机管理端生成密钥 ssh-keygen -t ed25519 # 将公钥拷贝到老机器 ssh-copy-id ubuntu192.168.x.x如果ssh-copy-id不好使手工把公钥追加到老机器的~/.ssh/authorized_keys注意权限必须是600~/.ssh目录权限700否则ssh直接拒绝使用密钥。这步权限不对是最容易忽略的入门坑。5.2 内存控制与zRAM跑到这里系统桌面约300MBFlask面板约30MB爬虫任务运行中峰值200MB左右1GB内存还有富余。但为了应付偶然的内存峰值比如多个cron任务同时跑建议启用zRAM替代传统swapsudo apt-get install zram-config sudo reboot重启后free -h里swap应该显示成zram设备这种交换是压缩内存而不是读写硬盘老机械硬盘不会因为交换而疯狂卡顿。与此同时把系统默认swappiness调低让系统尽量用物理内存不急着往swap赶echo vm.swappiness10 | sudo tee -a /etc/sysctl.conf sudo sysctl -p5.3 日志清理与磁盘卫生爬虫脚本每一行print输出都会进daily.log一两个月就能攒出几百MB——对160G老硬盘不算什么但对每天写入机械盘的损耗还是定期清理为妙。我配置了logrotatesudo vi /etc/logrotate.d/crawl内容如下/home/ubuntu/logs/*.log { daily rotate 7 compress missingok notifempty copytruncate }copytruncate非常关键如果直接mv新建日志文件正在写入的Python进程不会自动reopen文件日志会继续写到已被删除的inode上占着硬盘不释放。copytruncate先复制再清空原文件进程无感知。5.4 断电重启后自动拉起任务值守机最怕断电。除了给BIOS的“AC Power Loss”选项设为Power On以外系统启动后自动恢复脚本也很重要。14.04的rc.local还健在我直接在/etc/rc.local里加了恢复命令#!/bin/sh sleep 20 /home/ubuntu/venvs/spider/bin/python /home/ubuntu/webui.py /tmp/webui.log 21 exit 0sleep 20是为了等网络就绪否则Flask启动时bind不上端口。爬虫任务由cron驱动重启后cron服务自启不需要额外拉起。如果你需要更精细的守护可以用14.04的upstart。写一个/etc/init/crawl-job.confdescription crawl webui start on runlevel [2345] stop on runlevel [!2345] respawn exec /home/ubuntu/venvs/spider/bin/python /home/ubuntu/webui.pyrespawn让进程意外退出后自动重启比rc.local靠谱但写法略麻烦。我只在需要常驻的服务比如WebUI用upstart普通cron任务完全没必要。5.5 老硬件的散热与寿命实用主义06年的机器跑Linux发热不高但灰尘是最大敌人。我拆开后发现CPU散热器积灰严重清灰换硅脂之后温度从72度降到50度左右这是花两块钱换来的稳定性。另外如果CMOS电池快没电了每次断电重启时间都会归零影响cron执行的准确性时区错乱顺手换一颗CR2032电池几块钱能省很多事。老机器的SATA接口有时候接触不良特别是搬动过后开机找不到硬盘。遇到这种情况不要以为是系统坏了先重新插拔硬盘数据线和电源线。我在装完系统第三天遇到过一次“GRUB找不到”的报错最后发现是SATA线松动虚惊一场。5.6 爬虫被限制后的正确反应很多刚接触爬虫的朋友看到请求被403或要求验证码第一反应是“换IP”或“模拟更真实的浏览器特征”。但在这台老机器上被限制的正确反应其实是降低频率、退避重试、遵循robots。原因很简单应对方式风险老机器是否值得降低频率最低合法合规是加代理绕IP违反站点条款且代理维护复杂否Selenium模拟真人杀鸡用牛刀CPU扛不住否JS逆向或验证码打码涉灰黑产风险高绝对否我遇到过目标站突然在请求前加了一道JavaScript挑战发现后直接放弃该目标换用RSS和API几乎没有损失。做任何爬虫项目先把合规边界画出来比技术本身更重要。最后说点掏心窝的话这台06年的机器现在还躺在我办公桌下面的墙角除了每周清一下日志平时完全不打扰它。它带来的工作效率却是实打实的每天早上7点半自动抓取几十个公开页面8点生成日报我坐在工位上打开Web面板扫一眼就知道昨天的数据涨跌。这种“手里有台不值钱的机器让它去干脏活累活”的感觉比花大几千买云服务器舒坦得多。如果你也有一台吃灰的旧电脑别觉得它“毫无价值”。装Ubuntu 14.04、编译Python 3.9、跑几个定时脚本它就能从电子垃圾变成一台省电的内网值守机器人。关键在于搞清楚它的定位——不是让你重新用浏览器刷网页而是当后台工人干活。整个过程我踩过的坑都写在上面了照着做基本能绕开所有弯路。真遇到没写过的问题记住一条原则先手动跑命令看输出再拆环境变量最后查日志比瞎猜快十倍。