返回提交历史
Modified
g4f/Provider/Cloudflare.py
+1
-1
Modified
g4f/cookies.py
+2
-0
Modified
g4f/gui/server/website.py
+10
-14
Modified
g4f/requests/cdp.py
+10
-6
XFEstudio/gpt4free
Refactor Cloudflare session initialization and update BrowserConfig for headless mode
87ad30cc
代码差异
4 个文件
+23
-21
@@ -119,7 +119,7 @@ class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
119
119
pass
120
120
121
121
debug.log("Cloudflare: Starting CDPSession...")
122
session = CDPSession(headless=False)
122
session = CDPSession()
123
123
await session.start()
124
124
125
125
try:
@@ -77,6 +77,7 @@ class BrowserConfig:
77
77
impersonate: str = "chrome"
78
78
executable_path: str = None
79
79
connection_timeout: float = 0.25
80
headless: bool = True
80
81
81
82
@staticmethod
82
83
async def stop_browser():
@@ -86,6 +87,7 @@ class BrowserConfig:
86
87
def load_from_env(cls):
87
88
cls.port = os.environ.get("G4F_BROWSER_PORT", cls.port)
88
89
cls.host = os.environ.get("G4F_BROWSER_HOST", cls.host)
90
cls.headless = os.environ.get("G4F_BROWSER_HEADLESS", str(cls.headless)).lower() in ("1", "true", "yes")
89
91
cls.executable_path = os.environ.get(
90
92
"G4F_BROWSER_EXECUTABLE_PATH", cls.executable_path
91
93
)
@@ -148,11 +148,6 @@ class Website:
148
148
"function": self._playground,
149
149
"methods": ["GET"],
150
150
},
151
"/sillytavern/": {"function": self._sillytavern, "methods": ["GET"]},
152
"/sillytavern/<path:filename>": {
153
"function": self._sillytavern,
154
"methods": ["GET"],
155
},
156
151
"/apps/": {"function": self._apps, "methods": ["GET"]},
157
152
"/apps/<path:filename>": {"function": self._apps, "methods": ["GET"]},
158
153
"/stats/": {"function": self._stats, "methods": ["GET"]},
@@ -339,12 +334,12 @@ class Website:
339
334
"""
340
335
341
336
# Screenshot / logo section
342
logo_url = f"{(p.get('url', (p.get('base_url', p.get('baseUrl', '')))) or "").replace('playground.ai.', '').replace('https://', '').replace('http://', '').replace('api.', '').replace('console.', '').replace('api.', '').replace('router.', '').split('/')[0]}"
343
logo_url = f"api.airforce" if logo_url == "airforce" else logo_url
337
logo_url = f"{(p.get('url', (p.get('base_url', p.get('baseUrl', '')))) or "").replace('https://', '').replace('http://', '').replace('api.', '').replace('www.', '').replace('console.', '').replace('api.', '').replace('router.', '').split('/')[0]}"
338
logo_url = f"api.airforce" if logo_url == "airforce" else logo_url or "g4f.dev"
344
339
create_url = f"/screenshot?url=https://{logo_url}"
345
340
screenshot_html = f"""
346
341
<div class="screenshot-section">
347
<img src="/screenshot/{logo_url}" data-src="{create_url}" alt="{escape(p['name'])} logo" class="provider-logo"
342
<img src="/screenshot/{logo_url}.webp" data-src="{create_url}" alt="{escape(p['name'])} logo" class="provider-logo"
348
343
style="max-width:100%;border-radius:8px;border:1px solid var(--card-border)" />
349
344
<p class="screenshot-caption">Load screenshot from {escape(p['url'] or 'N/A')}</p>
350
345
</div>
@@ -387,13 +382,14 @@ class Website:
387
382
if (!previewRemoved && previewImg.parentNode) {{
388
383
previewImg.parentNode.removeChild(previewImg);
389
384
previewRemoved = true;
385
document.querySelector('.screenshot-caption').style.display = 'none';
390
386
}}
391
n = n + 1;
392
if (n <= 3) {{
393
setTimeout(() => {{
394
img.src = createSrc + `_${{n}}.webp`;
395
}}, 1000);
396
}}
387
// n = n + 1;
388
// if (n <= 3) {{
389
// setTimeout(() => {{
390
// img.src = createSrc + `_${{n}}.webp`;
391
// }}, 1000);
392
// }}
397
393
}};
398
394
img.onerror = () => {{
399
395
input.placeholder = 'Ask {escape(p.get("label", p["name"]))}';
@@ -325,7 +325,7 @@ class CDPSession:
325
325
port: Optional[int] = None,
326
326
host: Optional[str] = None,
327
327
user_data_dir: Optional[str] = None,
328
headless: bool = True,
328
headless: Optional[bool] = None,
329
329
):
330
330
if port is None:
331
331
port = BrowserConfig.port
@@ -335,7 +335,7 @@ class CDPSession:
335
335
host = "127.0.0.1"
336
336
self.port = port
337
337
self.host = host
338
self.headless = headless
338
self.headless = headless if headless is not None else BrowserConfig.headless
339
339
self.user_data_dir = (
340
340
user_data_dir # Ignored if using shared pool, but kept for compatibility
341
341
)
@@ -683,12 +683,17 @@ document.head.appendChild(debugEl);
683
683
const params = new URLSearchParams(window.location.search);
684
684
const searchQuery = params.get('q');
685
685
686
// 2b. Insert prompt in Flux HF before clicking on run button
687
const textbox = document.querySelector('[data-testid="textbox"]');
688
textbox ? textbox.value = searchQuery : null;
689
686
690
// 3. Click any "Accept" button in the main document or nested iframes
687
691
const targetTexts = [
688
692
'Send', 'Accept', 'Accept all', 'Accept All',
689
693
'Accept All Cookies', 'Accept all cookies',
690
694
'Einwilligen', 'Alle akzeptieren',
691
'Zustimmen und weiter', 'Zustimmen'
695
'Zustimmen und weiter', 'Zustimmen',
696
'Run'
692
697
];
693
698
const acceptBtns = (() => {
694
699
function searchDocument(doc, offsetX = 0, offsetY = 0) {
@@ -822,8 +827,7 @@ document.querySelector('[data-send-label="Send message"],'
822
827
823
828
// 8. Click the send button on gemini.google.com
824
829
const trigger = (el, etype) => {
825
const event = new Event( etype, { bubbles: true } );
826
el.dispatchEvent( event );
830
el.dispatchEvent( new Event( etype, { bubbles: true } ) );
827
831
};
828
832
setTimeout(() =>
829
833
trigger(document.querySelector(`.send-button`), `click`),
@@ -935,7 +939,7 @@ document.querySelector('[style="width: fit-content;"] [role="button"]')?.click()
935
939
print(url_without_suffix)
936
940
if ("&headless=false" in url_without_suffix or "&sleep=" in url_without_suffix or "&wait=" in url_without_suffix) and n == 3:
937
941
debug.log("Waiting 5 seconds for page to settle due to sleep/wait parameter...")
938
await asyncio.sleep(30)
942
await asyncio.sleep(120)
939
943
await self.wait_for_network_idle(idle_time=5, timeout=15.0)
940
944
result = await self.call("Page.captureScreenshot")
941
945
image_bytes = base64.b64decode(result["data"])