代理服务启动浏览器,pyppeteer操控已打开的浏览器;

先唠下目的和为啥要这么做

工作中,要而且必须用系统自带的浏览器,不是win系统,是国产的linux系统,当然浏览器也不能用google、火狐等;
但是自动化程序rpa类的根本无法进行交互,于是在win系统上写了通过代理服务方式启动,调试模式与浏览器交互的方法;
虽然有点笨,但是确实想不起来更好的办法了;如果更好的办法,还请大佬进行执教。2575968330@qq.com

获取浏览器信息

首先我们来启动Chrome的远程调试端口。你需要找到Chrome的安装位置,在Chrome的地址栏输入chrome://version就能找到Chrome的安装路径

#启动浏览器 文件路径/chrome.exe --remote-debugging-port=9222 "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port="9222"#win系统下 '/usr/share/browser/browser --remote-debugging-port=9222'#linux系统下 #debugurl, 在9222端口启动的浏览器地址栏,输入http://localhost:9222/json/version 即可获取debgu信息;获取webSocketDebuggerUrl http://localhost:9222/json/version ''' 下面这些是获取到的调试信息 { "Browser": "Chrome/111.0.5563.65", "Protocol-Version": "1.3", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", "V8-Version": "11.1.277.13", "WebKit-Version": "537.36 (@c710e93d5b63b7095afe8c2c17df34408078439d)", "webSocketDebuggerUrl": "ws://localhost:9222/devtools/browser/d7ba95df-c180-428f-8706-4ab9fd2dc2a9" } '''

调试模式启动浏览器的方法

手动启动

手动启动,cmd里面手动输入 ,即可直接启动,目前是指定google浏览器,也可以指定其他浏览器

"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port="9222"#win系统下

非阻塞模式,python调用系统命令启动

import subprocess import time browser_cmd = '"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port="9222"' aa=subprocess.Popen(browser_cmd, shell=True) # 继续执行其他代码 time.sleep(3)

需要说明下,subprocess属于子线程启动,不然会阻塞程序继续运行

webbrowser启动浏览器并跳转到指定的网址

webbrowser 当然这种方式也是会阻塞当前程序;

import webbrowser chrome_path = 'C:/Program Files/Google/Chrome/Application/chrome.exe --remote-debugging-port="9222" %s' # Chrome浏览器的路径 browser_cmd=webbrowser.get(chrome_path).open('https://baidu.com')

非阻塞模式 多线程webbrowser启动浏览器并跳转到指定网址下;

但是这种方法,子线程会一直处于运行状态;

import webbrowser import threading import time def open_browser(url): chrome_path = 'C:/Program Files/Google/Chrome/Application/chrome.exe --remote-debugging-port="9222" %s' # Chrome浏览器的路径 webbrowser.get(chrome_path).open(url) # 在新线程中启动浏览器 t = threading.Thread(target=open_browser, args=('https://baidu.com',)) t.start() # 继续执行其他代码 time.sleep(3) print('其他代码执行完成')

通过webbrowser进入当前已经打开浏览的指定页面

各种千秋吧,这种方法不是不行;cmd启动后,如果想直接进入某个页面,可以用这个方法;目前这方法,只能在新的标签页面里面进行打开网址,如果在当前标签页里面打开,还没找到方法;
毕竟cmd启动,也是有他的有优点的;

import webbrowser chrome_path = 'C:/Program Files/Google/Chrome/Application/chrome.exe --remote-debugging-port="9222" %s' # Chrome浏览器的路径 # webbrowser.get(chrome_path).open_new_tab('https://www.baidu.com/') webbrowser.get(chrome_path).open('https://www.baidu.com/')

用pyppeteer远程调试已经打开的浏览器,并进行操控

目前感觉这种形式还是可以,不会去打开新的页面,会在当前页面进行操作,唯一的缺点,就是窗口会变小;

import asyncio import json import requests from pyppeteer import connect response=requests.get('http://localhost:9222/json/version') data=response.text print(data) data_dic=json.loads(data) print(data_dic["webSocketDebuggerUrl"]) async def main(): # 连接到已经打开的浏览器 browser = await connect({'browserWSEndpoint': '%s'%data_dic["webSocketDebuggerUrl"]}) pages = await browser.pages() target_page = None # 遍历所有页面,找到指定的页面 for p in pages: if (p.url).find("gsxt") > 1: target_page = p break # 如果没有找到指定页面,则新打开一个页面 if target_page is None: target_page = await browser.newPage() await target_page.goto("https://www.baidu.com/") # 操控指定的页面 await target_page.setViewport({'width': 1200, 'height': 800}) # 设置浏览器窗口大小 '''可以使用querySelectorAll()方法获取'#primaryInfo > div > div.overview'下的所有子元素,然后使用evaluate()方法获取每个子元素的innerText属性,最后打印出来。''' elements = await target_page.querySelectorAll('#primaryInfo > div > div.overview > *') for element in elements: content = await target_page.evaluate('(element) => element.innerText', element) print(content) print("1") asyncio.get_event_loop().run_until_complete(main())

代理启动,直接接管9223端口,并且不进行改变浏览窗口的大小;

import asyncio from pyppeteer import connect async def main(): browser = await connect(browserURL='http://localhost:9223', defaultViewport=None) # 设置 defaultViewport 为 None pages = await browser.pages() page = pages[0] # 获取第一个页面,也可以根据需要选择特定页面 aa = await page.title() print(aa) # 运行异步函数 asyncio.get_event_loop().run_until_complete(main())