I have written a dynamic XPath as shown below:-
_FIRST_LIKE_TEXT_XPATH = "(//*[starts-with(#class,'%s-message')]/div/p)[%s]"
print(f"FIRST_LIKE_TEXT_XPATH with action and iteration = {self._FIRST_LIKE_TEXT_XPATH % action % str(itr)}")
action = like and itr = 1
expected output = (//*[starts-with(#class,'like-message')]/div/p)[1]
The error I am getting:-
TypeError: not enough arguments for format string
You use the python format function to pass variable in a string.
_FIRST_LIKE_TEXT_XPATH = "(//*[starts-with(#class,'{}-message')]/div/p)[{}]".format(action,str(itr))
Related
I am wondering if there is a way to use from string from lxml while including a variable ? For example, in my code :
new_elem = etree.fromstring("""<asl abortExpression="" elseExpression=""")
But, if I had a variable
x = "Tag"
and I wanted to add this variable to my fromstring parameter as '+x', is there a way to do this so it's
new_elem = etree.fromstring("""<asl abortExpression="" elseExpression=""" + x)
Right now I have the method below, it works perfectly fine but I want to change part of the self.wait_for_element(....) to instead use %s rather than calling str(counter)
> def gather_recent_visited_courses_in_content_switcher(self):
hover_courses = self.browser.find_elements_by_xpath("//div[contains(#class, 'recent-content flyout-closed')]")
course_list = []
counter = 1
for course in hover_courses:
self.hover_over(course)
# Change the below to %s
self.wait_for_element("//div[contains(#class, 'fly-wrapper recent-content-trigger')][" + str(counter) + "]//div[contains(#class, 'recent-content-info')]", 'Course list not found')
course_display_name = course.find_element_by_xpath("//div[contains(#class, 'recent-content-info')]").text
course_list.append(str(course_display_name))
counter += 1
return course_list
Currently I keep getting errors when replacing it with [%s], like below
> self.wait_for_element("//div[contains(#class, 'fly-wrapper recent-content-trigger')][%s]//div[contains(#class, 'recent-content-info')]", 'Course list not found' %(counter))
Does anyone have any ideas on how to get this to work properly? So far, I keep getting 'not all arguments converted during string formatting' errors
The reason why using %s isn't working is because you are setting the placeholder value in the second string argument, and not the first string as you have intended.
With the first argument:
"//div[contains(#class, ...)][%s]//div[... 'recent-content-info')]"
Python can't find the proper value to replace %s with in the first string argument. So, that will raise an error.
As for the second argument:
'Course list not found' % (counter)
You are passing a value to the string but the string cannot be formatted to use the passed value because the string doesn't have placeholder, %s. So, that'll raise an error too.
To fix that, just format the first string argument. It'll look like this:
"//div[contains(#class, '...')][%s]//div[..., 'recent-content-info')]" % counter
Alternatively, you can use .format(). This the new style of string formatting. Using %s is considered to be the old style[1].
"//div[contains(#class, '...')][{}]//div[..., 'recent-co...')]".format(counter)
NOTE: Strings have been redacted to make things easier to read.
References
[1] - https://pyformat.info/
How do i parse my received variables into arrays. I receive them from a site and i want to insert them into my firebird database but it would be a lot faster if i could do that through parsing it into a list.
This is how my flask code looks:
#app.route('/fddatumupdate', methods=['GET'])
def fddatumupdate():
datums = request.args.get('datums')
IDS1 = request.args.get('ids1')
IDS2 = request.args.get('ids2')
IDS3 = request.args.get('ids3')
print datums
print IDS1
print IDS2
print IDS3
#cur.execute("UPDATE OR INSERT INTO T_FOOD_DUTY (F_FD_DATE, F_US_ID1, F_US_ID2, F_US_ID3) values(%s, %s, %s) matching (F_FD_DATE)")
return("great succes")
This is the printing output so you can see how my data looks:
2017-5-15,2017-5-16,2017-5-17,2017-5-18,2017-5-19,2017-5-20,2017-5-21
27,36,26,435,26,30,31
27,28,30,435,27,28,26
30,28,30,28,29,28,27
I always get the error when i try to parse them from an NoneType to a string or array:
TypeError: unsupported operand type(s) for +: 'NoneType' and ...
You can split your string by , character and you will get a list:
print datums.split(',')
Alternatively, you can use list comprehensions to construct your list with some extra checking:
# example code
if datums: # this will check if 'datums' is None
print [i if i > 0 for i in datums.split(',')] # include element in list only if it is larger than 0
Found the answer, I parsed my received variables while i was receiving them en putthing them into my local variables. It needs to be like this then:
datums = request.args.get('datums')
IDS1 = request.args.get('ids1')
IDS2 = request.args.get('ids2')
IDS3 = request.args.get('ids3')
datumArray = str(datums).split(',')
IDS1Array = str(IDS1).split(',')
IDS2Array = str(IDS2).split(',')
IDS3Array = str(IDS3).split(',')
I am using Python 2.7 and Django 1.6.11 for my project and I want iterating to get a list of params with code like this:
for idx in range(1, int(number_unit_orders) + 1):
is_edit = request.POST.get('edit_%s'.format(str(idx)))
# Do something with is_edit
But the is_edit is always None although edit_1 and so on are set in the request object. But the code block below works(use string concatenation):
for idx in range(1, int(number_unit_orders) + 1):
is_edit = request.POST.get('edit_' + str(idx))
# Do something with is_edit
Wonder why this is the case.
'edit_%s'.format(str(idx))
Is mixing up two different types of formatting
You need to choose one of them and stick to it
'edit_%s' % str(idx) # 'edit_%d % idx
'test_{}'.format(idx)
The reason you're getting none is because you're trying to get an object that doesn't exist, it is actually currently looking up the exact string of edit_%s
In format method you don't use % but {}.
Please rewrite your line with this method to:
is_edit = request.POST.get('edit_{}'.format(idx))
Also explicit str is not needed.
Format doesn't work like that. Your code should be:
'edit_{0}'.format(str(idx))
I am writing a code to get specific information from yahoo finance website
page = requests.get('http://finance.yahoo.com/q/pr?s=%s')
tree=html.fromstring(page.text)
annual_report = tree.xpath('//td[#class="yfnc_datamoddata1"]/text()')
annual_report
Where %s is a name of a stock. If I manually input a name of a stock everything works great. But if I try to run a for loop for a list that I made,
for x in my_list:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s'),(x,)
tree=html.fromstring(page.text)
annual_report = tree.xpath('//td[#class="yfnc_datamoddata1"]/text()')
print annual_report
I get an error on tree line 'tuple' object has no attribute 'text'
Your mistake is:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s'),(x,)
Instead of formatting the string, you made 'page' a tuple.
This should work:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s' % (x,))
page = requests.get('http://finance.yahoo.com/q/pr?s=%s'),(x,)
This is not how to define a format string. You accidentally created a tuple ('http://finance.yahoo.com/q/pr?s=%s', x)
To incorporate x into the string write it like this:
page = requests.get('http://finance.yahoo.com/q/pr?s=%s' % x)
Or even better because not needing specifiers:
page = requests.get('http://finance.yahoo.com/q/pr?s={0}'.format(x))
page = requests.get('http://finance.yahoo.com/q/pr?s=' + x)