Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
534 views
in Technique[技术] by (71.8m points)

python - Replace a string in a textarea using selenium, "not reachable by keyboard"

I'd like to modify part of the text in a textarea with Selenium. The textarea seems almost as if it were read-only.

In this very simple example using a sample algo, it would be great to be able to change the stock id on this line:

context.aapl = sid(24)

... to something like:

context.aapl = sid(39840)

... which is the Tesla stock id. The variable name will no longer make sense, doesn't matter, just a start.

This Selenium code for me is able to open the sample with no login required.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

t = webdriver.Firefox()     # t stands for tab as in browser tab in my mind
t.implicitly_wait(10)
t.get('https://www.quantopian.com/algorithms/')
o = t.find_element_by_xpath("//body")       # o stands for object
o.send_keys(Keys.ESCAPE)                    # clearing the popup
o = t.find_element_by_link_text("Hello World Algorithm")
o.click()
''' for the fun of it if you want to run the backtest
o = t.find_element_by_xpath('//body')
o.send_keys(Keys.CONTROL + 'b')
o.send_keys(Keys.ESCAPE)
'''
print t.find_element_by_id('code-area').text

Here's the output from that

1
# Called once at the start of the simulation.
2
def initialize(context):
3
    # Reference to the AAPL security.
4
    context.aapl = sid(24)
5
6
    # Rebalance every day, one hour and a half after market open.
7
    schedule_function(my_rebalance,
8
        date_rules.every_day(),
9
        time_rules.market_open(hours=1, minutes=30))
10
11
# This function was scheduled to run once per day at 11AM ET.
12
def my_rebalance(context, data):
13
    14
    # Take a 100% long position in AAPL. Readjusts each day to
15
    # account for price fluctuations.
16
    if data.can_trade(context.aapl):
17
        order_target_percent(context.aapl, 1.00)

That id is 'code-area'. The content includes margin numbers which might be a problem. Next nested area is 'code-area-internal', seems the same. Followed by these two.

<div class='ide-container' id='ide-container'>
<textarea class='width_100pct' id='codebox'>

In trying to obtain the content of the algorithm with 'codebox', content doesn't appear to be present, just u'' ...

>>> p = t.find_element_by_id('codebox').text
>>> p
u''

Attempt to do CTRL-A on it results in this exception...

>>> o = t.find_element_by_id('codebox')
>>> o.send_keys(Keys.CONTROL + 'a')

ElementNotInteractableException: Message: Element is not reachable by keyboard

If the text can be completely cut, then replace can done in Python and paste, that would be fine. I wouldn't expect Selenium to be able to find and replace text, just surprised it finds a visible area for user input to be off limits from interactivity.

That textarea does have its own Find, and hoping won't have to resort to trying to use it as a workaround.

(The environment is an online IDE for stock market algorithms called Quantopian)

This is the one other thing I tried, with no apparent effect:

>>> t.execute_script("arguments[0].value = arguments[1]", t.find_element_by_id("ide-container"), "_new_")

Appreciate any pointers.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Textarea has style="display: none" attribute which means that you cannot get its content with text property. In this case you can use:

p = t.find_element_by_id('codebox').get_attribute("textContent")

To set new value to code field you can use:

field = driver.find_element_by_css_selector('div[role="presentation"]')
driver.execute_script("arguments[0].textContent = 'New value';", field)

But note that initially each code line in code field displayed as separate div node with specific value and styles. So to make new value looks exactly as code (in the same formatting) you can prepare HTML sample e.g.

value = """<div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -48px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 15px; width: 21px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment"># Comment for new code.</span></span></pre></div>"""

and do

driver.execute_script("arguments[0].innerHTML = arguments[1];", field, value)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...