

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>selenium &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/selenium/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Sat, 06 Apr 2024 04:58:42 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>selenium &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>chrome cdp Input.dispatchKeyEventchrome</title>
		<link>https://stackoverflow.max-everyday.com/2024/04/chrome-cdp-input-dispatchkeyeventchrome/</link>
					<comments>https://stackoverflow.max-everyday.com/2024/04/chrome-cdp-input-dispatchkeyeventchrome/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Sat, 06 Apr 2024 04:58:40 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5634</guid>

					<description><![CDATA[由於 nodriver 暫時還無法送出 Ente...]]></description>
										<content:encoded><![CDATA[
<p>由於 nodriver 暫時還無法送出 Enter，解法：</p>



<pre class="wp-block-code"><code>await tab.send(cdp.input_.dispatch_key_event("keyDown", code="Enter", key="Enter", text="\r", windows_virtual_key_code=13))
await tab.send(cdp.input_.dispatch_key_event("keyUp", code="Enter", key="Enter", text="\r", windows_virtual_key_code=13))</code></pre>



<p>nodriver 程式碼：<br><a href="https://github.com/ultrafunkamsterdam/nodriver/blob/main/nodriver/cdp/input_.py">https://github.com/ultrafunkamsterdam/nodriver/blob/main/nodriver/cdp/input_.py</a></p>



<p>DrissionPage 程式碼：<br>DrissionPage/DrissionPage/_functions/keys.py<br><a href="https://github.com/g1879/DrissionPage/blob/master/DrissionPage/_functions/keys.py">https://github.com/g1879/DrissionPage/blob/master/DrissionPage/_functions/keys.py</a></p>



<pre class="wp-block-code"><code>def send_key(page, modifier, key):
    """发送一个字，在键盘中的字符触发按键，其它直接发送文本"""
    if key not in keyDefinitions:
        page.run_cdp('Input.insertText', text=key, _ignore=AlertExistsError)

    else:
        description = keyDescriptionForString(modifier, key)
        text = description&#91;'text']
        data = {'type': 'keyDown' if text else 'rawKeyDown',
                'modifiers': modifier,
                'windowsVirtualKeyCode': description&#91;'keyCode'],
                'code': description&#91;'code'],
                'key': description&#91;'key'],
                'text': text,
                'autoRepeat': False,
                'unmodifiedText': text,
                'location': description&#91;'location'],
                'isKeypad': description&#91;'location'] == 3,
                '_ignore': AlertExistsError}

        page.run_cdp('Input.dispatchKeyEvent', **data)
        data&#91;'type'] = 'keyUp'
        page.run_cdp('Input.dispatchKeyEvent', **data)</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2024/04/chrome-cdp-input-dispatchkeyeventchrome/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Google Chrome memory saver &#8211; command line switch?</title>
		<link>https://stackoverflow.max-everyday.com/2024/04/google-chrome-memory-saver-command-line-switch/</link>
					<comments>https://stackoverflow.max-everyday.com/2024/04/google-chrome-memory-saver-command-line-switch/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 04 Apr 2024 22:28:29 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5628</guid>

					<description><![CDATA[如何手動啟用chrome 瀏覽器「Memory ...]]></description>
										<content:encoded><![CDATA[
<p>如何手動啟用chrome 瀏覽器「Memory Saver」, 解法：<br><a href="https://stackoverflow.com/questions/76938654/google-chrome-memory-saver-command-line-switch">https://stackoverflow.com/questions/76938654/google-chrome-memory-saver-command-line-switch</a></p>



<p>The setting seems to be here:&nbsp;<code>"C:\Users\&lt;username&gt;\AppData\Local\Google\Chrome\User Data\Local State"</code></p>



<pre class="wp-block-code"><code>{
    "autofill": {
        "states_data_dir": "C:\\Users\\&lt;username&gt;\\AppData\\Local\\Google\\Chrome\\User Data\\AutofillStates\\2020.11.2.164946"
    },
    "background_mode": {
        "enabled": false
    },
    "browser": {
        "enabled_labs_experiments": &#91;
            "memory-saver-multi-state-mode@1"
        ],
        "has_shown_refresh_2023_whats_new": true,
        "last_redirect_origin": "",
        "last_whats_new_version": 119,
        "shortcut_migration_version": "86.0.4240.75"
    },
    "data_use_measurement": {
        "data_used": {
            "services": {
                "background": {},
                "foreground": {}
.....
</code></pre>



<p>With the setting on&nbsp;<code>Default</code>&nbsp;it shows:&nbsp;<code>"browser":{"enabled_labs_experiments":[]</code></p>



<p><code>Enabled</code>&nbsp;shows:&nbsp;<code>"enabled_labs_experiments": ["memory-saver-multi-state-mode@1"]</code></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>寫入 Local Data 的範例程式碼：</p>



<pre class="wp-block-code"><code>def nodriver_overwrite_prefs(conf):
    state_filepath = os.path.join(conf.user_data_dir,"Local State")
    state_dict = {}
    state_dict&#91;"performance_tuning"]={}
    state_dict&#91;"performance_tuning"]&#91;"high_efficiency_mode"]={}
    state_dict&#91;"performance_tuning"]&#91;"high_efficiency_mode"]&#91;"state"]=1
    state_dict&#91;"browser"]={}
    state_dict&#91;"browser"]&#91;"enabled_labs_experiments"]=&#91;
        "memory-saver-multi-state-mode@1",
        "modal-memory-saver@1"
    ]
    json_str = json.dumps(state_dict)
    with open(state_filepath, 'w') as outfile:
        outfile.write(json_str)</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2024/04/google-chrome-memory-saver-command-line-switch/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to change preferences in Chrome by modifying files?</title>
		<link>https://stackoverflow.max-everyday.com/2024/04/how-to-change-preferences-in-chrome-by-modifying-files/</link>
					<comments>https://stackoverflow.max-everyday.com/2024/04/how-to-change-preferences-in-chrome-by-modifying-files/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 04 Apr 2024 20:07:34 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5625</guid>

					<description><![CDATA[如何修改 chrome 的預設參數，資料來源：h...]]></description>
										<content:encoded><![CDATA[
<p>如何修改 chrome  的預設參數，資料來源：<br><a href="https://superuser.com/questions/554233/how-to-change-preferences-in-chrome-by-modifying-files">https://superuser.com/questions/554233/how-to-change-preferences-in-chrome-by-modifying-files</a></p>



<p>解法：</p>



<p>There is a file called &#8220;Preferences&#8221; within the &#8220;User Data/&lt;Profile&gt;&#8221; folder that appears to contain these settings. The location of this file varies according to OS. For the &#8220;Default&#8221; profile this is located at:</p>



<h3 class="wp-block-heading">WinXP:</h3>



<pre class="wp-block-code"><code>C:\Documents and Settings\&lt;User Name&gt;\Local Settings\Application Data\Google\Chrome\User Data\Default\Preferences
</code></pre>



<h3 class="wp-block-heading">WinVista:</h3>



<pre class="wp-block-code"><code>C:\Users\&lt;User Name&gt;\AppData\Local\Google\Chrome\User Data\Default\Preferences
</code></pre>



<p>You then need to search for the appropriate setting in that file. I would close Chrome (and backup) first as this file appears to be updated automatically as you navigate tabs.</p>



<p>&#8220;<strong>Enable Auto-fill to fill in web forms in a single click.</strong>&#8221; appears to be stored here:</p>



<pre class="wp-block-code"><code>   "autofill": {
      "enabled": true,
</code></pre>



<p>&#8220;<strong>Offer to save passwords I enter on the web.</strong>&#8220;</p>



<pre class="wp-block-code"><code>      "password_manager_enabled": true,</code></pre>



<p></p>



<p>Deploy initial preferences:<br><a href="https://support.google.com/chrome/a/answer/187948?hl=en#zippy=%2Cstep-create-the-initial-preferences-file">https://support.google.com/chrome/a/answer/187948?hl=en#zippy=%2Cstep-create-the-initial-preferences-file</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>寫入 Preferences 的程式碼：</p>



<pre class="wp-block-code"><code>def nodriver_overwrite_prefs(conf, prefs_dict={}):
    prefs_filepath = os.path.join(conf.user_data_dir,"Default")
    if not os.path.exists(prefs_filepath):
        os.mkdir(prefs_filepath)
    prefs_filepath = os.path.join(prefs_filepath,"Preferences")
    prefs_dict&#91;"profile"]={}
    prefs_dict&#91;"profile"]&#91;"name"]=CONST_APP_VERSION
    prefs_dict&#91;"profile"]&#91;"password_manager_enabled"]=False
    json_str = json.dumps(prefs_dict)
    with open(prefs_filepath, 'w') as outfile:
        outfile.write(json_str)</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2024/04/how-to-change-preferences-in-chrome-by-modifying-files/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>selenium extension from unknown error: cannot read manifest</title>
		<link>https://stackoverflow.max-everyday.com/2023/12/selenium-extension-from-unknown-error-cannot-read-manifest/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/12/selenium-extension-from-unknown-error-cannot-read-manifest/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 25 Dec 2023 05:03:42 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5249</guid>

					<description><![CDATA[在寫好 chrome extension 後, ...]]></description>
										<content:encoded><![CDATA[
<p>在寫好 chrome extension 後, 透過 selenium 的 chrome_options.add_extension(ext), 測試其他的 extension 都正常, 但自己寫的 extension 會顯示錯誤訊息:</p>



<pre class="wp-block-preformatted">from unknown error: cannot read manifest</pre>



<p>執行畫面:</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="501" height="133" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/12/ConEmu64_2023-12-25_12-58_6t.png?v=1703480487" alt="" class="wp-image-5252"/></figure>



<p>發生的原因的確是無法讀取 manifest.json , 因為我直覺地直接壓縮目錄為 zip 檔, 應該要進去目錄裡再壓縮, 在多一層資料夾的情況下, 在解壓縮zip 後的根目錄是無法取得 manifest.json.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/12/selenium-extension-from-unknown-error-cannot-read-manifest/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>selenium 非同步 execute script 用法</title>
		<link>https://stackoverflow.max-everyday.com/2023/12/selenium-%e9%9d%9e%e5%90%8c%e6%ad%a5-execute-script-%e7%94%a8%e6%b3%95/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/12/selenium-%e9%9d%9e%e5%90%8c%e6%ad%a5-execute-script-%e7%94%a8%e6%b3%95/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 15 Dec 2023 15:18:14 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5207</guid>

					<description><![CDATA[直接執行 js ，就用 execute_scri...]]></description>
										<content:encoded><![CDATA[
<p>直接執行 js ，就用 execute_script() 就可以。</p>



<p>從 selenium 的source code 來看，有3種執行script 的方式，其中2個是非同步：<br><a href="https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/webdriver/remote/command.py">https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/webdriver/remote/command.py</a></p>



<pre class="wp-block-code"><code>W3C_EXECUTE_SCRIPT: str = "w3cExecuteScript"
W3C_EXECUTE_SCRIPT_ASYNC: str = "w3cExecuteScriptAsync"
EXECUTE_ASYNC_SCRIPT: str = "executeAsyncScript"</code></pre>



<p>範例python script</p>



<pre class="wp-block-code"><code>script = """
var callback = arguments&#91;arguments.length - 1]; 
window.setTimeout(function(){ callback('timeout') }, 3000);
"""
driver.execute_async_script(script)</code></pre>



<p>範例2號：</p>



<pre class="wp-block-code"><code>js = """var t = JSON.parse(Cookies.get("user")) ? JSON.parse(Cookies.get("user")).access_token : "";
fetch("%s",{headers: {
authorization: "Bearer ".concat(t)
}}).then(function (response) {
return response.json();
}).then(function (data) {
console.log(data);
if(data.result.product.length&gt;0)
if(data.result.product&#91;0].status=="pending") {
console.log("pending, start to reload");
location.reload();
}
}).catch(function (err){
console.log(err);
});
""" % getSeatsByTicketAreaIdUrl
driver.set_script_timeout(0.1)
driver.execute_async_script(js)</code></pre>



<p>說明：經測試，用使 jQuery 的 ajax 或是使用 fetch 的 promise 都無法在  ajax 傳回的那一個區塊使用下面的程式碼傳回資料：</p>



<pre class="wp-block-code"><code>var callback = arguments&#91;arguments.length - 1];
callback(data);</code></pre>



<p> variable scope 的問題，var callback 才需在 global scope 才可以成功地傳回值，不然 driver.execute_async_script() 的 javascript script 不論怎麼執行都會等到 timeout 也沒資料回傳。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>範例3號，常見 OCR 的：</p>



<pre class="wp-block-code"><code>driver.set_script_timeout(1)
form_verifyCode_base64 = driver.execute_async_script("""
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var img = document.getElementById('%s');
    if(img!=null) {
    canvas.height = img.naturalHeight;
    canvas.width = img.naturalWidth;
    context.drawImage(img, 0, 0);
    callback = arguments&#91;arguments.length - 1];
    callback(canvas.toDataURL()); }
    """ % (image_id))
if not form_verifyCode_base64 is None:
    img_base64 = base64.b64decode(form_verifyCode_base64.split(',')&#91;1])</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/12/selenium-%e9%9d%9e%e5%90%8c%e6%ad%a5-execute-script-%e7%94%a8%e6%b3%95/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Selecting all text in textarea using Python Selenium</title>
		<link>https://stackoverflow.max-everyday.com/2023/11/selecting-all-text-in-textarea-using-python-selenium/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/11/selecting-all-text-in-textarea-using-python-selenium/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 24 Nov 2023 08:08:51 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5179</guid>

					<description><![CDATA[在 python 的 selenium 裡全選後...]]></description>
										<content:encoded><![CDATA[
<p>在 python 的 selenium 裡全選後,輸入內容的用法如下:</p>



<pre class="wp-block-code"><code>builder = ActionChains(driver)
builder.move_to_element(el_text)
builder.click(el_text)
if platform.system() == 'Darwin':
    builder.key_down(Keys.COMMAND)
else:
    builder.key_down(Keys.CONTROL)
builder.send_keys("a")
if platform.system() == 'Darwin':
    builder.key_up(Keys.COMMAND)
else:
    builder.key_up(Keys.CONTROL)
builder.send_keys(val)
if submit:
    builder.send_keys(Keys.ENTER)
builder.perform()</code></pre>



<p>在 selenium 裡有 web element 程式碼在:<br>py/selenium/webdriver/remote/webelement.py</p>



<p>source code:</p>



<pre class="wp-block-code"><code>def send_keys(self, *value) -> None:
    """Simulates typing into the element.

    :Args:
        - value - A string for typing, or setting form fields.  For setting
          file inputs, this could be a local file path.

    Use this to send simple key events or to fill out form fields::

        form_textfield = driver.find_element(By.NAME, 'username')
        form_textfield.send_keys("admin")

    This can also be used to set file inputs.

    ::

        file_input = driver.find_element(By.NAME, 'profilePic')
        file_input.send_keys("path/to/profilepic.gif")
        # Generally it's better to wrap the file path in one of the methods
        # in os.path to return the actual path to support cross OS testing.
        # file_input.send_keys(os.path.abspath("path/to/profilepic.gif"))
    """
    # transfer file to another machine only if remote driver is used
    # the same behaviour as for java binding
    if self.parent._is_remote:
        local_files = list(
            map(
                lambda keys_to_send: self.parent.file_detector.is_local_file(str(keys_to_send)),
                "".join(map(str, value)).split("\n"),
            )
        )
        if None not in local_files:
            remote_files = &#91;]
            for file in local_files:
                remote_files.append(self._upload(file))
            value = "\n".join(remote_files)

    self._execute(
        Command.SEND_KEYS_TO_ELEMENT, {"text": "".join(keys_to_typing(value)), "value": keys_to_typing(value)}
    )</code></pre>



<p></p>



<p>網路上流傳的古時候的<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">錯誤</mark>用法1:</p>



<pre class="wp-block-code"><code>src_elem.click()
src_elem.send_keys(Keys.CONTROL, 'a') # select all the text
src_elem.send_keys(Keys.CONTROL, 'c') # copy it</code></pre>



<p>網路上流傳的古時候的<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">錯誤</mark>用法2:</p>



<pre class="wp-block-code"><code>String selectAll = Keys.chord(Keys.CONTROL, "a");
element.sendKeys(selectAll);</code></pre>



<p>或</p>



<p>Try to chord the&nbsp;<kbd>Ctrl</kbd>+<kbd>A</kbd>&nbsp;keys. The code below is working in my case:</p>



<pre class="wp-block-code"><code>element.sendKeys(Keys.chord(Keys.CONTROL, "a"));</code></pre>



<p>以上3個, 是錯誤示範, 會顯示 chord 並不存在。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/11/selecting-all-text-in-textarea-using-python-selenium/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Blocking API/URL/CSS in Selenium 4</title>
		<link>https://stackoverflow.max-everyday.com/2023/11/blocking-url-selenium/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/11/blocking-url-selenium/#comments</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 03 Nov 2023 03:57:12 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5126</guid>

					<description><![CDATA[常見的Google 服務會拖慢 selenium...]]></description>
										<content:encoded><![CDATA[
<p>常見的Google 服務會拖慢 selenium 效能, 除了使用 adblock plus 來 block connection 也可以設定在 selenium 裡.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>範例 1:<br><a href="https://stackoverflow.com/questions/46891301/can-i-automate-chrome-request-blocking-using-selenium-webdriver-for-ruby">https://stackoverflow.com/questions/46891301/can-i-automate-chrome-request-blocking-using-selenium-webdriver-for-ruby</a></p>



<pre class="wp-block-code"><code>driver.execute_cdp_cmd('Network.setBlockedURLs', {"urls": &#91;"www.baidu.com"]})
driver.execute_cdp_cmd('Network.enable', {})</code></pre>



<p></p>



<p>範例 2:<br><a href="https://github.com/ultrafunkamsterdam/undetected-chromedriver/issues/387">https://github.com/ultrafunkamsterdam/undetected-chromedriver/issues/387</a></p>



<pre class="wp-block-code"><code>import undetected_chromedriver as uc
driver = uc.Chrome()
driver.execute_cdp_cmd('Network.setBlockedURLs', {"urls": &#91;'*png','*woff2','*woff','*jpg','https://www.apple.com/ac/globalnav/7/en_US/styles/ac-globalnav.built.css']})
driver.execute_cdp_cmd('Network.enable', {})
driver.get('https://apple.com/')</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Java 版語法:</p>



<pre class="wp-block-code"><code>import org.junit.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v94.network.Network;

public class BlockURL {
      @Test
      public void blockUrl() {
            System.setProperty("webdriver.chrome.driver", "path to chromedriver");
            ChromeDriver driver = new ChromeDriver();
            DevTools devTool = driver.getDevTools();
            devTool.createSession();
            devTool.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
// Blocks all css files
            devTool.send(Network.setBlockedURLs(List.of("*.css"))); 
            devTool.addListener(Network.loadingFailed(), loadingFailed -> {
                  System.out.println("Blocking reason: " + loadingFailed.getBlockedReason().get());

            });

            driver.get("https://url.com");
      }
}</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/11/blocking-url-selenium/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>HTTP Proxy Authentication with Chromedriver in Selenium</title>
		<link>https://stackoverflow.max-everyday.com/2023/10/http-proxy-authentication-with-chromedriver-in-selenium/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/10/http-proxy-authentication-with-chromedriver-in-selenium/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 31 Oct 2023 02:11:46 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5107</guid>

					<description><![CDATA[如果不需要帳號/密碼, 是很快就解決 Setti...]]></description>
										<content:encoded><![CDATA[
<p>如果不需要帳號/密碼, 是很快就解決</p>



<p><em>Setting chromedriver proxy with Selenium using Python</em></p>



<p>If you need to use a proxy with python and Selenium library with chromedriver you usually use the following code (Without any username and password:</p>



<pre class="wp-block-code"><code>chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % hostname + ":" + port)
driver = webdriver.Chrome(chrome_options=chrome_options)
</code></pre>



<p>It works fine unless proxy requires authentication. if the proxy requires you to log in with a username and password it will not work. In this case, you have to use more tricky solution that is explained below. By the way, if you whitelist your server IP address from the proxy provider or server it should not ask proxy credentials.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>But, 大多數的proxy 應該要設帳號/密碼才合理, 因為不可能伺服器開在那, 給不認識的人使用, 解法:<br><a href="https://stackoverflow.com/questions/55582136/how-to-set-proxy-with-authentication-in-selenium-chromedriver-python">https://stackoverflow.com/questions/55582136/how-to-set-proxy-with-authentication-in-selenium-chromedriver-python</a></p>



<p><em>HTTP Proxy Authentication with Chromedriver in Selenium</em></p>



<p>To set up proxy authentication we will generate a special file and upload it to chromedriver dynamically using the following code below. This code configures selenium with chromedriver to use HTTP proxy that requires authentication with user/password pair.</p>



<pre class="wp-block-code"><code>import os
import zipfile

from selenium import webdriver

PROXY_HOST = '192.168.3.2'  # rotating proxy or host
PROXY_PORT = 8080 # port
PROXY_USER = 'proxy-user' # username
PROXY_PASS = 'proxy-password' # password


manifest_json = """
{
    "version": "1.0.0",
    "manifest_version": 2,
    "name": "Chrome Proxy",
    "permissions": &#91;
        "proxy",
        "tabs",
        "unlimitedStorage",
        "storage",
        "&lt;all_urls&gt;",
        "webRequest",
        "webRequestBlocking"
    ],
    "background": {
        "scripts": &#91;"background.js"]
    },
    "minimum_chrome_version":"22.0.0"
}
"""

background_js = """
var config = {
        mode: "fixed_servers",
        rules: {
        singleProxy: {
            scheme: "http",
            host: "%s",
            port: parseInt(%s)
        },
        bypassList: &#91;"localhost"]
        }
    };

chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});

function callbackFn(details) {
    return {
        authCredentials: {
            username: "%s",
            password: "%s"
        }
    };
}

chrome.webRequest.onAuthRequired.addListener(
            callbackFn,
            {urls: &#91;"&lt;all_urls&gt;"]},
            &#91;'blocking']
);
""" % (PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS)


def get_chromedriver(use_proxy=False, user_agent=None):
    path = os.path.dirname(os.path.abspath(__file__))
    chrome_options = webdriver.ChromeOptions()
    if use_proxy:
        pluginfile = 'proxy_auth_plugin.zip'

        with zipfile.ZipFile(pluginfile, 'w') as zp:
            zp.writestr("manifest.json", manifest_json)
            zp.writestr("background.js", background_js)
        chrome_options.add_extension(pluginfile)
    if user_agent:
        chrome_options.add_argument('--user-agent=%s' % user_agent)
    driver = webdriver.Chrome(
        os.path.join(path, 'chromedriver'),
        chrome_options=chrome_options)
    return driver

def main():
    driver = get_chromedriver(use_proxy=True)
    #driver.get('https://www.google.com/search?q=my+ip+address')
    driver.get('https://httpbin.org/ip')

if __name__ == '__main__':
    main()
</code></pre>



<p>Function get_chromedriver returns configured selenium webdriver that you can use in your application. This code is tested and works just fine.</p>



<p>Read more about&nbsp;<a href="https://developer.chrome.com/extensions/webRequest#event-onAuthRequired">onAuthRequired</a>&nbsp;event in Chrome.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/10/http-proxy-authentication-with-chromedriver-in-selenium/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>using python, Remove HTML tags/formatting from a string</title>
		<link>https://stackoverflow.max-everyday.com/2023/10/using-python-remove-html-tags-formatting-from-a-string/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/10/using-python-remove-html-tags-formatting-from-a-string/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 06 Oct 2023 09:15:26 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[String]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5073</guid>

					<description><![CDATA[在使用 selenium 時, 之前使用 ele...]]></description>
										<content:encoded><![CDATA[
<p>在使用 selenium 時, 之前使用 element.text 都可以正確地取得  TEXT 內容, 很奇怪, 目前使用 selenium 4.13.0 + python 3.9.13 在 Win 10 環境, 有時候會正常, 但有時會失敗, 可以確定取得的內容是正確的, 取得的 innerHTML 長這樣:</p>



<pre class="wp-block-code"><code>&lt;div data-v-337697a8="" class="sesstion-item">&lt;div data-v-337697a8="" class="row pa-4 flex-column flex-sm-row no-gutters">&lt;div data-v-337697a8="" class="col-sm-10 col-md-10 col-12">&lt;div data-v-337697a8="" class="row mx-0 flex-column flex-md-row no-gutters">&lt;div data-v-337697a8="" class="d-flex text-left font-weight-bold text-regular py-2 is-word-break col-sm-12 col-md-4 col-12 align-self-center">
                2023 JO1 1ST ASIA TOUR 'BEYOND THE DARK' LIMITED EDITION IN TAIPEI
              &lt;/div>&lt;div data-v-337697a8="" class="px-md-2 d-flex justify-md-center align-left align-md-center col-sm-12 col-md-2 col-12">&lt;div data-v-337697a8="" class="d-flex mb-2 mb-md-0">&lt;div data-v-337697a8="" class="grey--text text--darken-1 d-block d-md-none mr-2 wordBreakKeepAll">日期&lt;/div>&lt;div data-v-337697a8="">2023-11-11(六)&lt;/div>&lt;/div>&lt;/div>&lt;div data-v-337697a8="" class="px-md-2 d-flex justify-md-center align-md-center col-sm-12 col-md-2 col-12">&lt;div data-v-337697a8="" class="d-flex mb-2 mb-md-0">&lt;div data-v-337697a8="" class="grey--text text--darken-1 d-block d-md-none mr-2 wordBreakKeepAll">時間&lt;/div>&lt;div data-v-337697a8="">19:00&lt;/div>&lt;/div>&lt;/div>&lt;div data-v-337697a8="" class="px-md-2 d-flex justify-md-center align-md-center is-word-break col-sm-12 col-md-4 col-12">&lt;div data-v-337697a8="" class="d-flex mb-2 mb-md-0">&lt;div data-v-337697a8="" class="grey--text text--darken-1 d-block d-md-none mr-2 wordBreakKeepAll">地點&lt;/div>&lt;div data-v-337697a8="" class="text-left text-md-center location-content">
                    Zepp New Taipei
                    &lt;div data-v-337697a8="" class="grey--text text--darken-3 text-small d-inline d-md-block">
                      新北市新莊區新北大道四段3號8樓
                    &lt;/div>&lt;/div>&lt;/div>&lt;/div>&lt;/div>&lt;/div>&lt;div data-v-337697a8="" class="font-weight-bold col-sm-2 col-md-2 col-12 align-self-center">&lt;hr data-v-337697a8="" role="separator" aria-orientation="horizontal" class="d-block d-sm-none mb-5 mt-3 v-divider theme--light">&lt;div data-v-9536f93e="" data-v-337697a8="">&lt;!---->&lt;!---->&lt;!---->&lt;!---->&lt;button data-v-9536f93e="" type="button" class="nextBtn float-right v-btn v-btn--block v-btn--has-bg v-btn--rounded theme--dark v-size--default">&lt;span class="v-btn__content">立即購票&lt;/span>&lt;/button>&lt;!---->&lt;/div>&lt;/div>&lt;/div>&lt;!---->&lt;/div></code></pre>



<p>使用 .text 取得內容, 居然是空值! 但多試幾次, 偶爾可以取得正確的 text, 既然可以拿 innerHTML 就自己來去 tag 就好了. </p>



<pre class="wp-block-code"><code>import re
def striphtml(data):
    p = re.compile(r'&lt;.*?>')
    return p.sub('', data)

>>> striphtml('&lt;a href="foo.com" class="bar">I Want This &lt;b>text!&lt;/b>&lt;/a>')
'I Want This text!'</code></pre>



<p>Below you will find the syntax which require as per different binding. Change the&nbsp;<code>innerHTML</code>&nbsp;to&nbsp;<code>outerHTML</code>&nbsp;as per required.</p>



<p>Python:</p>



<pre class="wp-block-code"><code>element.get_attribute('innerHTML')</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/10/using-python-remove-html-tags-formatting-from-a-string/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Python] yield 和 return 有什麼不同?</title>
		<link>https://stackoverflow.max-everyday.com/2023/08/python-yield-return/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/08/python-yield-return/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 04 Aug 2023 20:15:10 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[selenium]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4974</guid>

					<description><![CDATA[使用Python很多年常常看到 yield，用這...]]></description>
										<content:encoded><![CDATA[
<p>使用Python很多年常常看到 yield，用這篇文將yield這個關鍵字重點整理一下。覺得整理的比較易懂的是這一篇：</p>



<p>How to Use Generators and yield in Python<br><a href="https://realpython.com/introduction-to-python-generators/">https://realpython.com/introduction-to-python-generators/</a></p>



<p>要列舉 Generators 裡的項目：</p>



<pre class="wp-block-code"><code>letters = &#91;"a", "b", "c", "y"]
it = iter(letters)
while True:
    try:
        letter = next(it)
    except StopIteration:
        break
    print(letter)</code></pre>



<p>也可以用 for 來列舉，會簡單很多：</p>



<pre class="wp-block-code"><code>letters = &#91;"a", "b", "c", "y"]
it = iter(letters)
for letter in it:
    print(letter)</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>yield 2 次，就可以 next 2 次：</p>



<pre class="wp-block-code"><code>&gt;&gt;&gt; def multi_yield():
...     yield_str = "This will print the first string"
...     yield yield_str
...     yield_str = "This will print the second string"
...     yield yield_str
...
&gt;&gt;&gt; multi_obj = multi_yield()
&gt;&gt;&gt; print(next(multi_obj))
This will print the first string
&gt;&gt;&gt; print(next(multi_obj))
This will print the second string
&gt;&gt;&gt; print(next(multi_obj))
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
StopIteration</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">yield和return一樣會回傳值，不過yield會記住上次執行的位置</h2>



<p>yield在下次迭代時會從上次迭代的下一行接續執行，一直執行到下一個yield出現，如果沒有下一個yield則結束這個生成器。</p>



<p>這個神奇例子：</p>



<pre class="wp-block-code"><code>def yield_test(n):
    print("start n =", n)
    for i in range(n):
        yield i*i
        print("i =", i)

    print("end")

tests = yield_test(5)
for test in tests:
    print("test =", test)
    print("--------")
</code></pre>



<p>執行結果：</p>



<pre class="wp-block-code"><code>start n = 5
test = 0
--------
i = 0
test = 1
--------
i = 1
test = 4
--------
i = 2
test = 9
--------
i = 3
test = 16
--------
i = 4
end</code></pre>



<p>可以解釋為 遇到 yield 時，程式就會「暫時」被結束返回且相等於 return 會傳回值，但程式本身還保留在記憶體中，等下一次被 next() 呼叫，或 while 與 for 下一個 iter() 時，接續之前 yield 之後的程式碼。</p>



<p>目前我遇到的程式碼在這：<br><a href="https://github.com/ultrafunkamsterdam/undetected-chromedriver/blob/1c704a71cf4f29181a59ecf19ddff32f1b4fbfc0/undetected_chromedriver/init.py#L716">https://github.com/ultrafunkamsterdam/undetected-chromedriver/blob/1c704a71cf4f29181a59ecf19ddff32f1b4fbfc0/undetected_chromedriver/<strong>init</strong>.py#L716</a></p>



<pre class="wp-block-code"><code>def find_elements_recursive(self, by, value):
    """
    find elements in all frames
    this is a generator function, which is needed
        since if it would return a list of elements, they
        will be stale on arrival.
    using generator, when the element is returned we are in the correct frame
    to use it directly
    Args:
        by: By
        value: str
    Returns: Generator&#91;webelement.WebElement]
    """
    def search_frame(f=None):
        if not f:
            # ensure we are on main content frame
            self.switch_to.default_content()
        else:
            self.switch_to.frame(f)
        for elem in self.find_elements(by, value):
            yield elem
        # switch back to main content, otherwise we will get StaleElementReferenceException
        self.switch_to.default_content()

    # search root frame
    for elem in search_frame():
        yield elem
    # get iframes
    frames = self.find_elements('css selector', 'iframe')

    # search per frame
    for f in frames:
        for elem in search_frame(f):
            yield elem</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/08/python-yield-return/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
