I'm trying to loop through a list of ID's and submit each option with a value = id.
After submitting I am grabbing the resulting text I need from the last row of a table.
The basic functionality works, however, when I add more than one 'ID' to the list it only returns the result for last item in the list.
Here is my code:
#Go To Email Logs
driver.get("https://website.com/manager/email_logs.php")
#variables
SaleIds = ['47832', '47842', '49859', '50898']
dropdown = Select(driver.find_element_by_id('emailspecialid'))
options = dropdown.options
for option in options:
value = option.get_attribute('value')
for id in SaleIds:
if id == value:
option.click()
driver.find_element_by_tag_name('input').submit()
result = driver.find_element_by_xpath('/html/body/table[1]/tbody/tr[last()]/td[4]').text
driver.implicitly_wait(100)
print(result)
Related
I have a function that checks if a barcode is known to the warehouse. If so, the function grabs the row from the dataframe (occupied by an imported excel file) and will be inserted into a treeview with known items. If the barcode is unknown it will be inserted into a listbox.
The function works and does what it is supposed to do, but I want to expand it by updating the row in the treeview by increasing its quantity by 1 when adding the same barcode to the treeview. See the picture for the current behaviour. Known items treeview
# Function to process new entered barcodes by filtering known and unknown items and adding them to treeview
def scan_check(event):
scanned_item = scan_entry.get()
for code in df.iloc[:, 1]: # column with barcodes
if code == scanned_item:
for row in df.to_numpy().tolist(): # dataframe with item / barcode / item description / size / quantity
if scanned_item in row:
quantity_count = 1
row.insert(4, quantity_count)
scanTree.insert(parent='', index='end', value=row)
for child in scanTree.get_children():
if scanTree.item(child, option='values'[3]) in scanTree.get_children():
quantity_count += 1
scanTree.set(child, 'Quantity', quantity_count)
scan_entry.delete(0, tkinter.END)
break # to prevent adding item to unknown products listbox as well
else:
unknown_listbox.insert(tkinter.END, scanned_item)
scan_entry.delete(0, tkinter.END)
My question is: How would I write the if clause, after iterating throught the children, when I want to check if the added row from the dataframe is already in my treeview?
My attempts at the if clause did not work obviously. I was hoping anyone could help me with my problem. Thanks for reading.
You can simplify the logic:
Search the treeview first for the barcode, if found, update the quantity
If not found, search the dataframe. If found, insert new record into treeview, otherwise insert the barcode to the unknown listbox
def scan_check(event):
scanned_item = scan_entry.get().strip()
if scanned_item == '':
# do nothing if empty string is input
return
# search treeview
for child in scanTree.get_children():
row = scanTree.set(child)
if row['Barcode'] == scanned_item:
# update quantity
scanTree.set(child, 'Quantity', int(row['Quantity'])+1)
break # prevent executing else block
else:
# search dataframe
result = df.loc[df['Barcode'].astype(str) == scanned_item]
if result.empty:
# should check whether barcode already exists?
unknown_listbox.insert('end', scanned_item)
else:
scanTree.insert('', 'end', values=result.iloc[0].to_list()+[1])
scan_entry.delete(0, 'end')
I want to build a URL-shortener which should work as follows:
shortener saves the original URL typed in by user, the automatically generated numeric ID of the original URL and the base 62-encoded version of the numeric ID.
with each new entered original URL, those 3 types of information are saved into a pandas data frame as columns;
the data frame is empty in the beginning; when the first row is inserted, a random numeric ID is generated; the IDs of following rows are incremented by 1
the process of insertion should have following logic:
User gets asks for input (the original URL)
a check is conducted, whether this URL is already contained in the database; if it is, the user gets asked to enter a new URL
if the URL is not contained in the database yet, the script checks if there are other entries in the database yet
if there are no entries, the entered URL gets inserted into the data frame with a randomly generated ID (which is used as the index of the data frame) and the encoded ID
if there are other entries available, the entered Url gets inserted into the data frame with an ID that is the last available ID in the data frame + 1
What I want to achieve is to operate on the same data frame without creating copies of the data frame with each new entry. So the main function should each time receive the same data frame and update it with new rows. However, when I execute the code below, and the script gets to the point of executing the line
database = database.append(row)
in the update_database-function, I get the following error:
UnboundLocalError: local variable 'database' referenced before assignment
This seems strange, because the variable database is defined on the global scope right on top of the main function, so each function within the main function should have access to it. Can anyone tell me where I'm going wrong?
import numpy as np
import pandas as pd
import string
import random
#create the 62-base for encoding
digits = [str(i) for i in list(np.arange(0,10))]
letters_upper = list(string.ascii_uppercase)
letters_lower = list(string.ascii_lowercase)
base_62 = digits + letters_upper + letters_lower
#create the empty database with ID as index
database = pd.DataFrame(columns = ['ID', 'URL_long', 'URL_short']).set_index("ID")
#create the 62-base encoded version of the ID
def encode_id(num,base, base_size):
result = []
while divmod(num,base_size) != (0,0):
el = base[divmod(num,base_size)[1]]
result.append(el)
num = divmod(num,base_size)[0]
result.reverse()
return "".join(result)
def main(df):
database = df
#asks user for input
def user_input():
print("exec user_input")
return input("Enter your URL: ")
#if the entered URL is not in the data frame yet, inserts the URL with ID and encoded ID
def update_database(passed_input_value):
print("exec_update_database")
#executes if the data frame is empty
if len(database) == 0:
first_id = int("".join(random.sample(string.digits,7)))
row = pd.Series({"URL_long": passed_input_value, "URL_short": encode_id(first_id,base_62,62)})
row.name = first_id
#executes if the data frame already has entries
else:
last_id_incr = int(df.index[-1]+1)
row = pd.Series({"URL_long": passed_input_value, "URL_short": encode_id(last_id_incr,base_62,62)})
row.name = last_id_incr
#appends the created row to the data frame
#this is where the error happens
database = database.append(row)
#checks if the entered URL is already in the data frame
#if it is, redirects to the beginning of the process
#if it's not, passes the value of the input to the update-function and executes it
def check_duplicates():
print("exec_check_duplicates")
input_value = user_input()
if input_value in database["URL_long"].unique():
url_available = database[database["URL_long"]==input_value].iloc[0]['URL_short']
print(f"URL already shortened: {url_available}.")
check_duplicates()
else:
update_database(input_value)
check_duplicates()
return database
main(database)
I am new using python and I am trying to get some values from a table in a webpage, I need to get the values in yellow from the web page:
I have this code, it is getting all the values in the "Instruments" column but I don't know how to get the specific values:
body = soup.find_all("tr")
for Rows in body:
RowValue = Rows.find_all('th')
if len(RowValue) > 0:
CellValue = RowValue[0]
ThisWeekValues.append(CellValue.text)
any suggestion?
ids = driver.find_elements_by_xpath('//*[#id]')
if 'Your element id` in ids:
Do something
One of the ways could be this, since only id is different.
Homework is a python notebook project in Watson. Homework provides below codes for function get_basketball_stats(link="..."). However it return erroneous result: dictionary's value and key are dis-matched, i.e. Key "PPG" is given "GP"'s values.
I tried the same codes in google Colab. The result is correct. Google colab python version is 3.6.7. I suspect that the outdated python version in Watson (3.5.5) causes the erroneous dictionary, and hence I ask the question here: how to upgrade Watson's python version?
def get_basketball_stats(link='https://en.wikipedia.org/wiki/Michael_Jordan'):
# read the webpage
response = requests.get(link)
# create a BeautifulSoup object to parse the HTML
soup = bs4.BeautifulSoup(response.text, 'html.parser')
# the player stats are defined with the attribute CSS class set to 'wikitable sortable';
#therefore we create a tag object "table"
table=soup.find(class_='wikitable sortable')
#the headers of the table are the first table row (tr) we create a tag object that has the first row
headers=table.tr
#the table column names are displayed as an abbreviation; therefore we find all the abbr tags and returs an Iterator
titles=headers.find_all("abbr")
#we create a dictionary and pass the table headers as the keys
data = {title['title']:[] for title in titles}
#we will store each column as a list in a dictionary, the header of the column will be the dictionary key
#we iterate over each table row by fining each table tag tr and assign it to the objed
for row in table.find_all('tr')[1:]:
#we iterate over each cell in the table, as each cell corresponds to a different column we all obtain the correspondin key corresponding the column n
for key,a in zip(data.keys(),row.find_all("td")[2:]):
# we append each elment and strip any extra HTML contnet
data[key].append(''.join(c for c in a.text if (c.isdigit() or c == ".")))
# we remove extra rows by finding the smallest list
Min=min([len(x) for x in data.values()])
#we convert the elements in the key to floats
for key in data.keys():
data[key]=list(map(lambda x: float(x), data[key][:Min]))
return data
I expect the keys to match their corresponding values in Watson like Google Colad does.
I am fetching results out of a query from a table:
def getdata()
self.cursor.execute("....")
fetchall = self.cursor.fetchall()
result ={}
for row in fetchall:
detail1 = row['mysite']
details2 = row['url']
result[detail1] = row
return result
Now I need to process the result set as generated :
def genXML()
data = getdata()
doc = Document() ""create XML tree structure"""
Such that data would hold all the rows as fetched from query and I can extract each column values from it? Somehow I am not getting the desired out. My requirement is to fetch result set via a DB query and store result into a placeholder such that I can easily access it later in other method or locations?
================================================================================
I tried the below technique but still in method 'getXML()' I am unable to get each dict row so that I can traverse and manipulate:
fetchall = self.cursor.fetchall()
results= []
result={}
for row in fetchall:
result['mysite'] = row['mysite']
result['mystart'] = row['mystart']
..................................
results.append(result)
return results
def getXML(self):
doc = Document()
charts = doc.createElement("charts")
doc.appendChild(charts)
chartData = self.grabChartData()
for site in chartData:
print site[??]
So how do I get each chartData row values and then I can loop for each?
Note: I found that only last row fetched values are getting printed as in chartData. Say I know that 2 rows are getting returned by the query. Hence in case I print the list in getXML() method like below both rows are same:
chartData[0]
chartData[1]
How can I uniquely add each result to the list?
Here you are modifying and adding the same dict to results over and over again:
result={}
for row in fetchall:
result['mysite'] = row['mysite']
result['mystart'] = row['mystart']
..................................
results.append(result)
Create the dictionary inside the loop to solve this:
for row in fetchall:
result={}