ClericPy / ichrome

Chrome controller for Humans, based on Chrome Devtools Protocol(CDP) and python3.7+.
https://pypi.org/project/ichrome/
MIT License
227 stars 29 forks source link

How to set not to open the browser? and don't output "True" #124

Closed jiahe224 closed 1 year ago

jiahe224 commented 1 year ago

This project is really awesome, but I didn't find the documentation, my code is as follows:

url = f'https://wglh.com/stock/historyshares/{code}/' async with AsyncChromeDaemon() as cd: async with cd.incognito_tab(proxyServer='http://127.0.0.1:8080') as tab: await tab.goto(url, timeout=10) html = await tab.html

In fact, I don't understand the meaning of the code, just refer to "Quick Start" written.

ClericPy commented 1 year ago

能说中文吧...

你不想启动浏览器, 就在 AsyncChromeDaemon 里面加参数 headless=True, 就是无头模式了, incognito_tab 是隐私(无痕)模式开一个 tab, 这模式下面可以挂单独的代理, 也可以不继承原浏览器的缓存和 Cookie, 用完干干净净. 大部分文档实际上在源码里面, 从 IDE 跳转过去会有部分文档

jiahe224 commented 1 year ago

感谢!感谢!真厉害,本来想着看源码应该能找到相关的,但不是主要工作,只是尝试用用就没仔细研究,试玩后感觉比 selenium 太简洁了,👍

jiahe224 commented 1 year ago

@ClericPy "Quick Start" 里的函数执行是不是可以改为 await test() ?参考这个:https://stackoverflow.com/questions/55409641/asyncio-run-cannot-be-called-from-a-running-event-loop-when-using-jupyter-no

jiahe224 commented 1 year ago

添加什么参数能取消输出“True”?

image

jiahe224 commented 1 year ago

再问个问题,我将代理改为 http://127.0.0.1:7890(Clash端口是7890)后依然不能使用 Clash 中的代理,该怎么设置才行呢?另外对于目标网站,chrome可打开,ichrome 返回 403 - Forbidden: Access is denied.

ClericPy commented 1 year ago

@ClericPy "Quick Start" 里的函数执行是不是可以改为 await test() ?参考这个:https://stackoverflow.com/questions/55409641/asyncio-run-cannot-be-called-from-a-running-event-loop-when-using-jupyter-no

你该参考的是 asyncio 和协程的教程, await 是协程的主要用法之一, 其他还有 asyncio.create_task 来提供并发能力等

然后输出的 True 是因为你用了交互模式, 实际上没代码会输出到 stdout 里去.

cd.incognito_tab(proxyServer='http://127.0.0.1:8080') 这种设置代理的方式在 Windows 上可能会无效, 主要是给 linux 下面尤其是 Chromium 来使用的, 是个实验室功能, Windows 上可以在 async with AsyncChromeDaemon(proxy='xxxxxxx') as cd: 这里直接绑定整个浏览器的代理

ClericPy commented 1 year ago

你的 clash 我没用过, 403 是不是你没带上代理的帐号密码?

jiahe224 commented 1 year ago

你的 clash 我没用过, 403 是不是你没带上代理的帐号密码?

再次感谢指导,我推测403是因为封了“网络出口”之类的东西,因为我让同事尝试也是返回403(估计全公司被封了,每人的IP固定),网络切换为手机热点后可以访问(但奇怪的是网页能打开,tab.goto 获取到的还是403,系统代理是关闭的)。目前没用IP代理池,直接复制的示例中的 proxyServer='http://127.0.0.1:8080/',还以为走本地是必须的,原来只是示例😓 如果不封IP,proxyServer 是不是不用加?另外如果要在 async with AsyncChromeDaemon 中加代理的话,IP 和 端口赋值给 proxy,帐号密码的变量名分别是 user 和 password 吗?看源码里 pass_auth_proxy 函数是这么定义的。

jiahe224 commented 1 year ago

@ClericPy "Quick Start" 里的函数执行是不是可以改为 await test() ?参考这个:https://stackoverflow.com/questions/55409641/asyncio-run-cannot-be-called-from-a-running-event-loop-when-using-jupyter-no

你该参考的是 asyncio 和协程的教程, await 是协程的主要用法之一, 其他还有 asyncio.create_task 来提供并发能力等

然后输出的 True 是因为你用了交互模式, 实际上没代码会输出到 stdout 里去.

cd.incognito_tab(proxyServer='http://127.0.0.1:8080') 这种设置代理的方式在 Windows 上可能会无效, 主要是给 linux 下面尤其是 Chromium 来使用的, 是个实验室功能, Windows 上可以在 async with AsyncChromeDaemon(proxy='xxxxxxx') as cd: 这里直接绑定整个浏览器的代理

可能是因为交互模式的原因,不修改的话就报错,RuntimeError: asyncio.run() cannot be called from a running event loop。即便重启电脑重新运行也是这样,不明白此时为什么会有“running”,不深究了,交互模式不是主流使用方式,我在jupyter里改改,然后在笔记里备注下就好。

jiahe224 commented 1 year ago

又分别测试了一下几个库,chrome可正常打开网页的情况下:

  1. requests 获取正常

header = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9", "cache-control": "no-cache", "sec-ch-ua": '"Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'document', 'sec-fetch-mode': 'navigate', 'sec-fetch-site': 'same-origin', 'sec-fetch-user': '?1', "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" } r_text = requests.get(url,headers=header,timeout=(21.1, 21.1)).text df_tmp = pd.read_html(r_text)[0]

  1. selenium 获取正常

options = webdriver.ChromeOptions() # 避免 USB 报错(由 Chrome 尝试读取当前挂起的 USB 设备的属性触发) options.add_experimental_option('excludeSwitches', ['enable-logging']) # 禁用 window.navigator.webdriver,避免返回 Nginx forbidden options.add_argument('--disable-blink-features=AutomationControlled') # 不打开浏览器 options.add_argument('headless') # 解决无头模式访问被拒绝 options.add_argument(f'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36')

driver = webdriver.Chrome(executable_path='D:\hkex\chromedriver.exe',options=options) driver.get(url) time.sleep(2) #这是为了让网页能够完全加载出来 # 获取网页源码 html = driver.page_source driver.quit() # driver.close() df_tmp = pd.read_html(html)[0]

  1. ichrome 无头返回 403,有头正常

async with AsyncChromeDaemon(headless=True) as cd: async with cd.incognito_tab() as tab: await tab.goto(url, timeout=10); html = await tab.html; df_tmp = pd.read_html(html)[0]

如何修改 ichrome,使其无头模式下也可获取网页内容?

ClericPy commented 1 year ago

async with cd.connect_tab() as tab: 是默认的 tab, incognito_tab 是无 Cookie 的隐私模式. 具体为啥 403 我也没法测, 你抓包看看请求怎么发出去的, 可以考虑用 playWright 试试, 那个比较热门.

要么你试试调试模式看看, python -m ichrome -t --headless 启动, 然后 await tab.goto(url), 然后 await tab.html 看看. 可能性太多了, 浏览器不一样有时候都可能有问题