前言

我有些时候想要我们公司组织架构和人员名单,但是又不能从企业微信直接导出,就想着能不能从OA里爬出来,在分析浏览器请求时,我发现这是Ajax异步请求得到的:

然而,这个请求被加密过了,完全看不出来怎么做的:

所以我就想能不能截取Selenium的请求,网上查了一圈,好像BrowserMob Proxy最靠谱。

前期准备

1 安装java

前往官网下载:https://www.oracle.com/cn/java/technologies/downloads/

我安装的是jdk19-windows,链接是https://download.oracle.com/java/19/latest/jdk-19_windows-x64_bin.exe

安装好之后,记得把java的安装路径加到环境变量中

2 安装相关的Python模块

pip install browsermob-proxy

3 下载 browsermob-proxy 的二进制文件

项目地址:https://github.com/lightbody/browsermob-proxy

下载地址:https://github.com/lightbody/browsermob-proxy/releases/download/browsermob-proxy-2.1.4/browsermob-proxy-2.1.4-bin.zip

4 测试启动监听服务器

我是直接在Jupyter Notebook中测试的

from browsermobproxy import Server
server = Server(r"C:\jupyter\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat") # 注意替换路径
server.start()
proxy = server.create_proxy()

没有报错的话就差不多了。

实战测试

# 导入相关模块
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from browsermobproxy import Server
import json

# 创建browsermobproxy监听服务器
server = Server(r"C:\jupyter\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat") # 注意替换路径
server.start()
proxy = server.create_proxy()

# 打开Chrome
chrome_options = Options()
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--proxy-server={}'.format(proxy.proxy))
driver = webdriver.Chrome(options=chrome_options)

开始监听(这里不写a=也可以,但是有些时候在JupyterNotebook中会有输出结果,看起来不太美观)

a = proxy.new_har(options={
        'captureContent': True,
        'captureHeaders': True
    })

使用Selenium控制Chrome进行一些操作触发Ajax,也可以直接用鼠标点点点

然后看下已经截取了多少操作

print(len(proxy.har['log']['entries']))
> 25

看下其中一条响应的结构

proxy.har['log']['entries'][6]['response']['content']
> {'size': 10425,
 'mimeType': 'application/json;charset=utf-8',
 'text': '[{"fname":"******","avatarUrl":"***","sortNumber":***,"username":"***"…………………………

看样子返回的是Json格式的数据,只不过以字符串的形式存储在text中,而且每条员工信息中都有username字段,那我就写一个生成器,把监听到的结果都解析出来。

# 定义一个解析截取的response的生成器
def parse_response(proxy):
    for entry in proxy.har['log']['entries']:
        if 'text' in entry['response']['content'].keys():
            if 'username' in entry['response']['content']['text']:
                yield json.loads(entry['response']['content']['text'])
                
# 根据生成器整合json到列表li中
gen = parse_response(proxy)
li = []
for x in gen:
    li = li+x
    
# 看下采集了多少信息
print(len(li))
> 283

接下来稍微改成自动化的,就可以把所有人的信息都爬下来了,还可以设成定时任务呢。