截至2020年8月底,上海共有市场主体281万余户,其中企业231万余户。随着企业数量快速增加和市场活动日益频繁,上海市市场监督管理局在2019年底开通了“上海市企业登记档案网上查询系统”,对司法机关、税务局、律师、金融机构等开放,相信已有许多同行体验过网上档案查询系统的便利。
不过笔者在网上调档时,发觉还是有一些繁琐的地方,例如登录流程比较长,企业的具体档案需要一份份点击打开并下载,下载时文件名均为默认的downloadPdf.pdf(即有重命名的必要性)。需要调取一两家企业信息时还可以,但在复杂案件中,面对几十家甚至上百家企业调档需求,难免要花费大量时间精力。这时,如果有个“一键打包下载”按钮,该多好!
求人不如求己,作为面向搜索引擎编程的爱好者,笔者利用业余时间在网上找了一圈轮子,总算用Python+Selenium造出了一辆自动挡(Win10环境)。在律师手机收到查询成功的短信后,只要输入企业名称,就能在后台下载并整理该企业的内档。源码附在文末。
一、模拟“档案网上查询系统”登陆
Selenium是一套自动化测试框架,可以用语句告诉浏览器我们要进行哪些操作,例如访问网站-get、找到某个按钮(术语为“定位元素”)-find_element、输入文本-send_keys、鼠标单击-click、鼠标拖曳-ActionChains.click_and_hold.perform、获取网页源代码-get_source等等,不用自己去操控键盘和鼠标。以最常见的百度搜索为例,可以拆解为以下几个步骤:
//*[@id="kw"]为何代表输入框?可以看下面这张动图:
同理,对“百度一下”单击右键,进入“检查”页面后复制其Xpath路径,可以得到//*[@id="su"]。这样一来,find_element_by_xpath就能找到“百度一下”这个按钮了。
依样画葫芦,要登录网上调档系统(http://fw.scjgj.sh.gov.cn/achieve_outer/apply/loginTip),首先会跳转到“上海一网通办”网站的登录界面,进行实名认证。这里采用账号密码登录,因为微信/支付宝扫码登录一般需要手机的配合,比较复杂。
接着出现一个难点:点击“登录”后要求通过滑块验证,需要计算出鼠标拖曳的距离(像素)。此处还是利用定位元素,得到拼图、背景图这两张图片的base64编码,并转化为图片格式,按照网页比例进行缩放。网上教程通常使用opencv库中的模板匹配方法(matchTemplate),算出拼图在整幅图片中的位置,从而得出需要滑动的距离。
随后将鼠标定位到滑块元素上,根据距离进行拖动即可~(这里居然不用模拟自然运动轨迹就可以通过验证,所以象征性地拖动两次滑块,直接到缺口部分)如果显示验证失败,就在网页刷新后再计算、拖动一回,直到成功为止。
最后比较简单,依次点击【电子档案查询】-【律师事务所查询】-【法人一证通登录】对应的元素,输入法人一证通的密码,点击登录即可(别忘了事先插入U盾,打开协卡助手)。附上一张完整的动图:
二、分析企业档案存放结构与下载地址
我们最终的目的是要把企业内档中所有PDF文件批量下载至本地,首先可以观察PDF文件的下载地址。
发现网址开头都是:fw.scjgj.sh.gov.cn/achieve_outer/apply/downloadPdf?type=sg&path=,后面加上了一串字符。这串字符是怎么得来的呢?
在“档案目录”中点击右键,查看框架源代码。
发现源代码中记录了各文件夹、各文件的组织结构,即红圈2中的内容,是列表中嵌套字典的格式,可用pandas库进行处理。

红圈1则为企业档案目录的网址,很容易知道appNo=后面的字符就是该企业的特定编号。这串字符肯定也藏在某处的源代码中,和企业名称有着一一对应的关系。
回到“历史查档记录”页面,查看框架源代码。
用BeautifulSoup库清洗后,发现在源代码的table_list类中,清晰展现了企业名称和其对应的appno。可以再将其整理为列表形式(通过正则匹配),方便通过企业名称查询appno。
总结一下,想要得到企业内档所有PDF文件的下载地址,步骤依次为:登录网上调档系统→查找源代码中的table_list→根据企业名称获取appno→进入档案目录→获取源代码中记录的文件组织结构、文件/文件夹名称、下载地址等。
关于源代码的获取方式,既可以用Selenium的get_source方法,也可以用requests库。要注意先把登录后cookie保存下来(只需要其中的JSESSIONID值),这样用requests.get方法来访问调档系统时,服务器就会识别到我们处于已登录的状态。
三、下载文件-进行重命名-移入文件夹
在我们点击企业的某项内档时,通常浏览器会自动调用内置的PDF阅读器,在新标签中打开PDF并显示打印、下载、编辑按钮等。这也是比较浪费时间的地方。要更快速地下载PDF文件,可以禁用这项设置。在Chrome浏览器中,进行如下操作:
当然,现在我们全程使用Selenium就更方便了,只要在浏览器启动时用语句配置一下就行。
每当一个PDF下载完毕,就要对其进行重命名(即上文获取的name),并放入文件夹中。所幸我们已经掌握了文件存放的组织结构,根据pId确定文件夹的名称,使用自带的os库创建文件夹,用shutil.move语句移动PDF文件,同时对其重命名即可。
最后,我们要把打开浏览器的整个过程都隐去,实现真正的无界面后台下载。Selenium也提供了“无头模式”,在配置中加上add_argument('--headless')。
All Done!
四、环境安装与日常维护
1、安装Python
如果在教科书上,这一部分肯定放在文章开头了,先要介绍安装过程和环境变量Path的设置。想输出一句Hello World就得对着书本先鼓捣半天,无疑打击了很多人的积极性。但现在各类语言的安装和配置越来越简单,就像Python,只要在官网下载安装包即可进行安装,唯一需要注意的是过程中注意勾选Add to PATH。
2、安装第三方库
上文还提到了很多“库”,书面说法是“完成一定功能的代码集合”。打个比方,我们知道电话机就是用来打电话的,那么这个库可以叫做Telephone。而电话可能包含很多功能,比如致电-call、重拨-recall、音量-voice、录音-record等,这些围绕电话功能的具体函数就在Telephone库内。本文代码需要用到的库如下:
要使用第三方库,需要通过pip工具在Windows命令行(cmd)中进行安装(碰到超时的话,用国内安装源会快一些),再用import导入。而标准库在python安装时就已包含在内了。
3、下载Webdriver
Selenium模拟浏览器操作时,调用的并非电脑里本身安装的浏览器,而是经过特殊配置的Webdriver,其支持主流的浏览器,包括Chrome/Firefox/Edge/IE等。以Chrome为例,目前本地版本为86.0.4240.111,需要在http://chromedriver.storge.googleapis.com或镜像网站http://npm.taobao.org/mirrors/chromedriver下载对应版本后,解压出chromedriver.exe,放入Python安装目录下。
这里也会引发一个问题,即Webdriver版本需要和本地浏览器一致,而本地浏览器经常会有大版本的自动更新,导致程序运行出错。解决此问题的方法有两种,一是禁止自动更新,保持Webdriver版本与本地浏览器一致;二是发现程序因Webdriver版本问题出错时,再去下载最新的Webdriver。
五、后记
这篇文章前前后后写了很久,有部分原因是工商网上调档系统、一网通办网站在不断更新,登录页面、文件存储结构都发生了变化。使用过最早时期调档系统的律师肯定会记得,当时登记通知书、名称核准通知书、指定代表或者共同委托代理人收取委托书、投资人名录、公司章程、营业执照等内容都单独呈现为PDF文件。若企业多次办理变更手续,每个时间节点的文件夹下都有十几个PDF。如果所以要下载并整理一家稍有历史的企业内档,有时可能要花费整整一天的时间。这也是笔者开始研究如何用编程来批量下载的初衷。
现在的调档系统已经颇为人性化,至少每个时间节点下的档案都合并成为一个PDF文件了。从登陆网站到完整下载一家企业的档案,手动操作基本可以在十分钟内完成。当然,用代码后台下载还是迅速不少,同时不会影响手头上别的工作,何乐而不为~
有人说用Python写程序就像玩电子积木一样,容易入门、开发快速,但一般只能用于小型项目。笔者作为初学者也深有此感,在法律工作范围内,对于网站检索(爬虫)、批量文件/邮件处理、数据可视化等方面,都可以编写一些脚本,提升效率的同时又能享受搭积木的乐趣。后附源码以及py文件下载链接,请专业人士轻拍,也希望能与爱好科技的斜杠法律人多多交流。
律师如何利用简易编程避免重复劳作
作者:邵洋来源:星瀚微法苑

截至2020年8月底,上海共有市场主体281万余户,其中企业231万余户。