编写爬虫追踪世界银行黑名单
效果展示
该程序提供网页版,可供在线或者缓存后离线使用。
点击链接访问:追踪世界银行黑名单-网页版
待解决的问题
跟踪世界银行黑名单,及时确定指定的数家公司是否出现在该黑名单上。这一跟踪应该自动反复运行。
对问题的分析
世界银行黑名单网站的地址如下:
https://www.worldbank.org/en/projects-operations/procurement/debarred-firms
解决方案
手动检查
在浏览器中,可以按Ctrl+F,输入所需公司名称。也可以点击Download按钮,下载表格,通过Excel查找。
无代码爬虫
考虑使用EasySpider。该项目在GitHub上获得了43.7k Stars,声誉较好。使用时,请注意它采用AGPL-3.0许可证。如果修改后部署或分发应当公开源代码。
EasySpider的GitHub储存库如下:
https://github.com/NaiboWang/EasySpider
我不建议使用EasySpider完成这一任务。原因有四:
- EasySpider通过图形用户界面编写逻辑,修改和调试较为繁琐。
- 其性能和输入输出方式有限。
- 它依赖Chrome加载网页。但是,世界银行的网站使用了性能很差的JavaScript代码。如我们所见,加载那个黑名单需要很长时间。在EasySpider上支持这样的分段加载的网页不比编写代码容易。
- 实际上,它提供了有限的便利,但几乎没有提供认知捷径。用户仍然需要理解什么是XPath。
写一个Python爬虫
这是解决这种问题的通用方案。
编写Python爬虫的一般步骤
打开网页
这一步的目的是判断:
- 网页是否可以打开
- 网页是否对(请求头)Header,尤其是用户代理(User Agent,UA)加以歧视
- 网页上是否直接出现了所需信息
- 所需信息是否需要经过登录、付费等认证方式
- 信息是否以文字方式呈现
检查元素&查看源代码
这一步的目的是判断:
- 所需信息是直接由HTTP(S)返回还是依赖JavaScript
- 如果是直接返回:如何解析DOM(Document Object Model,文档对象模型),定位所需的元素(通常使用XPath即可满足大多数需求)
- 如果是JavaScript:模仿浏览器(使用Selenium)或者调用同一API
查看HTTP(S)请求
在浏览器的开发者工具(通常使用F12唤出)中,选择“网络”选项卡(某些浏览器仅提供英文版的开发者工具,此时为“Network”)。
重点关注XHR。
事实上,在本例中,到这一步,问题已经解决了。
表示所得的数据
将所得数据表示出来,以进一步处理。表示数据可以使用基于纯文本的格式(JSON、CSV)等,便于通过代码处理。如需与办公人员协作,使用XLSX。
编写代码
这一步可以使用AI解决。当前的AI对编写Python爬虫很有造诣。
事实上,Python并不是一门易于掌握的编程语言。它显得清晰,却隐藏了许多实现上的细节。例如下面这段代码。
a = []
b = a
a.append("1")
print(b) # 修改a,但b也被改动了。这是因为a和b指向同一个列表(list)。
a = ["2"] # 给a重新赋值。
print(b) # b原封不动。因为赋值语句只是让a指向另一个列表。
b = a.copy() # 这样才能使b指向与a的各个元素和排列顺序一致的另一个列表。
由此可见,Python代码可读性很强,却很不易于编写。需要专门学习这门语言的许多细节。因此推荐使用AI起草Python代码,并加以调试。
使用AI编写代码时,一般而言,遵循以下原则,可以提高效率。
-
某些付费的AI性能较强,但免费额度很有限。如果确信可以在少数步骤内解决问题,才使用它们。
-
大多数AI喜欢就同一问题提供多种方案,或者针对各种可能的输入尽可能防御性编程。这样会让上下文的焦点变得不清晰。如果开发自己用的便捷脚本,或者先实现可用原型的阶段,不要让AI这样做。在提示词中明确:就同一问题仅提供一种代码解决方案,并且该方案尽可能简洁(即使可能无法正常处理某些不规范的输入)。
-
只让AI编写你不想写的部分。如果你只希望AI编写一个函数,就在提示词中明确:仅编写一个接受某某参数,返回某某值,具有某某副作用(行为)的函数。
-
全面地提供信息。将前面找到的JavaScript甚至整个网页源代码复制下来,发送给AI。如果只发送URL,AI可能懒得读,或者明明没读假装已读。
-
合理使用Claude Code、OpenClaw、Hermers、Copilot等Agent。
运行你的解决方案
使用命令行
在Windows上,按Win+R,输入powershell,回车。Windows的版本应当为10或者11。
在macOS上,找到“终端”并运行它。
在其他桌面端操作系统(Linux、BSD……),我默认你知道如何使用命令行。
安装Python和Pip
在Windows上,通过scoop包管理器安装Python,步骤如下:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
scoop install python
在macOS上,使用Homebrew包管理器安装python,步骤如下:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install python
在其他桌面端操作系统上,我默认你知道如何安装Python和Pip。
将代码保存为文件
直接从AI处下载代码,或者将AI编写的代码复制到文本编辑器中,保存为tracker.py。
应当确保你能看见后缀名,而不是隐藏它。
安装依赖
要求AI提供requirements.txt。它应该知道,这个文件名通常意味着一份包含完整依赖包的清单。将它保存到文件。
安装和使用依赖时,永远记得使用venv。这是为了隔离不同项目的依赖,避免相互冲突和破坏系统的完整性。
python -m venv ./venv
在Windows上激活venv:
.\venv\Scripts\Activate.ps1
在其他任何操作系统环境中激活venv:
source ./venv/bin/activate
运行
确保你处于venv中,执行:
python tracker.py
如果没有报错,那么就成功了。
报错解决和调试
如果出现报错,请复制完整的错误信息,和其他尽可能多的相关信息,并提供给可以帮助你解决问题的一方(包括但不限于:我、AI、论坛帖子、搜索引擎),或者试着查阅文档。
对于调试而言,显然,要在一节课的时间内讲清楚如何使用调试器是不可能的。请使用input()在需要的位置暂停程序。使用print()输出中间值。这样往往可以解决大部分问题。
自动比对
现在你得到了一个可以自动下载数据的脚本。或许你可以利用它下载所需数据,然后手动比对。这样仍然很麻烦。你需要另一个比对数据的脚本。
我不建议将两个脚本合二为一。因为,下载和比对并不总是必须同时进行。写成两个脚本给你提供了灵活性。当然,也可以写成一个脚本,接受不同的参数,决定它是否同时下载和比对。但我仍然建议拆分它们。**一个工具只做一件事。**这个理念非常实用。比如,你可以复用你的比对脚本,用于比对其他来源的数据。
只需要提供来源文件和目标文件,或者清晰地描述它们的格式,告诉AI,“帮我写一个对比工具cmp.py。它遍历来源XLSX文件中,除了A列除第一横行(标题行)之外的每个单元格,将其字符串与目标XLSX文件的每个单元格比对,并输出匹配到一个新的XLSX。……”
这样,本项目的代码撰写就完成了。
实时更新
这样得到的两个脚本,运行一次后,就会自动退出。如果希望反复检查,实时跟踪,那么只需要反复运行它们就好了。同样地,一个工具只做一件事。可以编写一个新脚本赖运行之前的两个脚本。更简单的方式是利用Shell的循环功能,或者系统提供的其他工具。
在Windows的PowerShell中,只需要:
while ($true) {
python tracker.py
python cmp.py
Start-Sleep -Seconds 60 # 等待 60 秒
}
在其他任何系统中,系统通常提供了watch工具。使用方式非常简单:
watch 'python tracker.py && python cmp.py'
其中&&表示,只有前一个命令成功退出,才运行后一个命令。
后续的优化
可以加入通知功能(如声音通知、邮件通知等)。具体方法可以自行查询。
当脚本多次运行无法获取数据,说明所跟踪的网页发生了变更,需要重新制作脚本。脚本可以在多次获取不到数据时发出警告通知。