0%

python | 通过 selenium 获取接口信息

在写脚本的时候,通常有这样一个需求,我们在网页中点击按钮,会向服务器发送请求,然后服务器返回数据。

但是,如果发送的请求中有网页自己的加密方式那就很难伪造了。

这个时候,我们一般选用 selenium ,但是,我们使用 selenium 的时候,看不到接口数据。「通过 F12Network 查看」

这一章,将教授如何用 selenium 获取接口数据。


参考资料



原理


browsermob-proxy 创建了代理接口,所有的请求都通过该接口发出去,当有信息回来的时候,browsermob-proxy 可以把通过接口的信息都获取到。


使用


环境

  • MacBook
  • chrome

安装

安装 browsermob-proxy

在上面 github 中,下载 ***-bin.zip 文件,解压。

在解压的文件夹的 bin 路径下,分别有

  • browsermob-proxy
    • 用于 MacBookLinux
  • browsermob-proxy.bat
    • 用于 wins

python 安装第三方库

pip install browsermob-proxy

使用

使用的过程非常简单,下面是网上 win 的代码,要是用 MacBook 就把 Server 中的文件路径换一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import json
from browsermobproxy import Server
from selenium.webdriver.chrome.options import Options
from selenium import webdriver


if __name__ == '__main__':
# 开启Proxy
server = Server(r'D:\usr\data\browser\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat')
server.start()
proxy = server.create_proxy()

# 配置Proxy启动WebDriver
chrome_options = Options()
chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))
# 解决 您的连接不是私密连接问题
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--ignore-urlfetcher-cert-requests')
driver = webdriver.Chrome(chrome_options=chrome_options)

proxy.new_har("douyin", options={'captureHeaders': True, 'captureContent': True})
driver.get(url)
result = proxy.har


for entry in result['log']['entries']:
_url = entry['request']['url']
# 根据URL找到数据接口
if "/hotel/list" in _url:
_response = entry['response']
_content = _response['content']['text']
# 获取接口返回内容
print(_content)
# 读取信息
person_json = json.loads(_content)
hotels = (person_json["data"])["hotels"]

server.stop()

进阶

使用网络代理

如果,我们本地的电脑还有其他代理,即翻墙之类的操作,上面的代码是运行不了的,因为,所有的网络请求都定向走 browsermob-proxy 创建的端口,而不会走翻墙端口。

所以,想要网络走翻墙端口,解析走 browsermob-proxy 端口,按照下面的书写方式。

proxy = server.create_proxy({"httpProxy":"61.155.141.13:20345"})

httpProxy 填上你的科学上网信息。

彻底关闭端口

下面的是网上的资料,我没试过。

每次打开 Browsermob-Proxy 后,都会使用一个新端口,直接调用 server.stop() 方法并不能真正的关闭这个端口,我们可以通过按住 ctrl 建点击 server.stop() 底层进去找到之后,添加一段代码进行强制杀掉每次使用完毕后不用的端口。

具体参考

1
2
3
4
5
6
7
8
9
10
###添加以下内容
find_port = 'netstat -aon|findstr %s' % self.port
result = os.popen(find_port)
text = result.read()
pid_line = text.split('\n', 1)[0]
pid = pid_line.replace(" ", "").split("LISTENING")[1]
find_kill = 'taskkill -f -pid %s' % pid
result = os.popen(find_kill)
cmd = result.read()
cmd.close()

不过,我每次启动确实会留下非常多的端口。

请我喝杯咖啡吧~