I am trying to click on a button using selenium and python but I can not click it.
<div id="environmentNavigation" class="yui-navset yui-navset-top">
<ul class="yui-nav">
<li nav="myDash" class="" title="">
<a href="#" hidefocus="true">
<em>My dashboard</em>
</a>
</li>
<li nav="myApp">
<a href="#" hidefocus="true">
<em>My applications</em>
</a>
</li>
<li nav="myPermits" class="" title="">
<a href="#" hidefocus="true">
<em>My permits</em>
</a>
</li>
<li nav="allPermits" class="" title="">
<a href="#" hidefocus="true">
<em>All permits</em>
</a>
</li>
<li nav="myDetails" class="selected" title="active">
<a href="#" hidefocus="true">
<em>My Details</em>
</a>
</li>
</ul>
</div>
This is the HTML source, I want to click on All permits button I tried using XPath,link_text but nothing worked. please help me here. The website is confidential which requires login so I can't share it, your help would be much appreciated.
Webdriver object:
driver=webdriver.Chrome(executable_path=chromedriver_path)
driver.get('https://myminesonline.business.qld.gov.au/suite/apps')
wait=WebDriverWait(driver,10)
Full XPATH:
wait.until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[1]/div/div[2]/ul/li[4]'))).click()
XPATH:
wait.until(EC.element_to_be_clickable((By.XPATH,'//*[#id="environmentNavigation"]/ul/li[4]'))).click()
Thanks
driver.page_source
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<title>My dashboard | Appian Application Portal</title>
<meta http-equiv="content-type" content="text/html">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
<link rel="shortcut icon" href="/suite/portal/img/appian_16x16.ico?appian_environment=">
<link rel="icon" href="/suite/portal/img/appian_48x48.png?appian_environment=" sizes="48x48">
<link rel="icon" href="/suite/portal/img/appian_32x32.png?appian_environment=" sizes="32x32">
<script type="text/javascript">
(function() {
var hash = window.sessionStorage && sessionStorage.getItem(\'hash\');
if (hash) {
sessionStorage.removeItem(\'hash\');
window.location = window.location + hash;
}
// do not use h:rewrite or c:url because the path already indicates
// the environment, and we don\'t want the environment to show up in the address bar
var envPath = \'/suite/apps\';
// validate browser URL is that of the current environment
var envPathRegEx = /\\/suite\\/apps/i;
var isAddressBarOk = !!top.location.href.match(envPathRegEx);
if (!isAddressBarOk) {
top.location.href = envPath;
return;
}
// validate that we don\'t try to load index inside index (infinite loop)
if (top != self) {
var isTopIndex = !!top.fContent; // assume if there\'s fContent in top, then top is index.jsp
if (isTopIndex) {
// index.jsp ended up nested in itself; default to environment entry point
top.fContent.location.href = \'/suite/portal/loadEnvironmentHome.do?appian_environment=apps\';
} else {
top.location.href = envPath;
}
return;
}
})();
window.APPIAN = {
};
</script>
</head>
<frameset rows="*, 0" border="0">
<frame name="fContent" id="fContent" src="/suite/portal/loadEnvironmentHome.do?appian_environment=apps" noresize="" title="Main Content Frame">
</frameset>
<noframes>
This site requires frames. Please turn on frame support in your web browser.
</noframes>
</html>
It seems that the tag I require is not inside these. What should I do now?
Body tag copied from the inspect element
<body class="yui-skin-sam" onload="if (typeof timeout == 'function') { timeout(); }" onbeforeunload="window.eventCache.flushAll();" data-new-gr-c-s-check-loaded="14.1002.0" data-gr-ext-installed=""><iframe id="_yuiResizeMonitor" style="position: absolute; visibility: visible; width: 10em; height: 10em; top: -124px; left: -124px; border-width: 0px;"></iframe>
<a id="skipNavigationLink508" href="#environmentContent">Jump to content</a>
<script type="text/javascript">
window.decorator = 'main';
if (isIE) { $("body").addClass("isIE"); }
</script>
<div id="bodyDecoratorContainer">
<iframe name="fProcess" id="fProcess" style="display:none;position:absolute;width:600px;height:400px;margin:100px;top:0;left:0px;z-index:100;" src="/suite/portal/blank.jsp" title="Background processing frame. No displayed content."></iframe>
<iframe name="popupTarget" id="popupTarget" style="display:none;" src="/suite/portal/blank.jsp" title="Background processing frame. No displayed content."></iframe>
<div id="mainContent" style="">
<div id="environmentHeader">
<div class="a1">
<div class="b1">
<img src="/suite/portal/img/skins/default/app.gif" id="applicationIcon" alt="Application"></div>
<div class="b2 appName" id="applicationName" title="MyMinesOnline - Click here to view available applications">MyMinesOnline</div>
<div class="b3">
<div id="topNavItemsMenu" class="yuimenu yui-module yui-overlay" style="position: absolute; visibility: hidden;">
<div class="bd">
<ul class="first-of-type">
<li topnavid="myminesonline" id="yui-gen0" class="yuimenuitem first-of-type" groupindex="0" index="0">
<a href="#" title="" class="yuimenuitemlabel">
MyMinesOnline
</a>
</li>
</ul>
<div class="dividerContainer"><div class="menuDivider"></div></div>
<ul class="first-of-type">
<!-- Remove comments to re-enable dropdown items.
<li topNavId="system.tasks" >
<a href="#">
Tasks
</a>
</li>
<li topNavId="system.alerts" >
<a href="#">
Alerts
</a>
</li>
-->
</ul>
</div>
</div>
<script>
(function(){
YAHOO.widget.MenuManager.removeMenu(YAHOO.widget.MenuManager.getMenu('topNavItemsMenu'));
var menu = new YAHOO.widget.Menu('topNavItemsMenu', {
maxheight: 400,
scrollincrement: 2,
context: ["applicationNameLink",
YAHOO.widget.Overlay.TOP_RIGHT,
YAHOO.widget.Overlay.BOTTOM_RIGHT]
});
menu.hide();
var showFn = function () {
menu.render();
menu.align();
menu.show();
}
YAHOO.util.Event.addListener('applicationName', 'click', showFn, null, menu);
var menuElements = $("#topNavItemsMenu li");
for (var i = 0; i < menuElements.length; i++) {
var menuItem = menuElements.get(i);
YAHOO.util.Event.addListener(menuItem, 'click', function(){
var topNavId = this.getAttribute('topNavId');
ApplicationPortalUtils.loadTopNavigation(topNavId, ApplicationPortalUtils.defaultNavItem);
return false;
}, menuItem);
}
})();
</script></div>
</div>
<div class="a2">
<div class="c1">
<div class="d1">
<!-- Remove comment tags to re-enable links.
<a hidefocus="true" href="/suite/tempo" class="headerTempoIcon" title='Launch Tempo in new window' target="tempoWindow">Tempo</a>
<a hidefocus="true" href="#" class="sprite inbox" onclick="ApplicationPortalUtils.loadTopNavigation('system.tasks', ApplicationPortalUtils.defaultNavItem); return false;">Tasks<span class="taskCount"></span></a>
<a hidefocus="true" href="#" class="sprite alerts" onclick="ApplicationPortalUtils.loadTopNavigation('system.alerts', ApplicationPortalUtils.defaultNavItem); return false;">Alerts<span class="notificationCount"></span></a>
-->
<a hidefocus="true" href="#" class="sprite preferences" onclick="backgroundAction('/portal/updateUserPreferences.do','asiDialog');" title="Click to modify preferences">anitalee.ishere#yahoo.com</a>
<!--
<a hidefocus="true" href="https://docs.appian.com/suite/help/19.3" target="_blank" class="sprite help" title="Open User Guide in new window" hidefocus="hidefocus">Help</a>
-->
<a hidefocus="true" href="#" class="sprite logout" onclick="logout();">Sign Out</a>
</div>
</div>
<div class="c2">
<a id="logo" href="#" onclick="return false;"><img src="/suite/portal/img/skins/default/companylogo.png" height="31px" alt="MyMinesOnline"></a>
</div>
</div>
<div class="clearboth"></div>
</div>
<script>
(function(){
$("#logo").click(function(){
var homeApplicationId = '';
if (!StringUtils.isBlank(homeApplicationId)){
ApplicationPortalUtils.loadTopNavigation(homeApplicationId, ApplicationPortalUtils.defaultNavItem);
}
return false;
});
})();
</script>
<div id="environmentNavigation" class="yui-navset yui-navset-top">
<ul class="yui-nav">
<li nav="myDash" class="" title=""><em>My dashboard</em></li><li nav="myApp"><em>My applications</em></li><li nav="myPermits"><em>My permits</em></li><li nav="allPermits" class="" title=""><em>All permits</em></li><li nav="myDetails" class="selected" title="active"><em>My Details</em></li></ul>
<div class="yui-content"><div style="display: none;"></div><div style="display: none;"></div><div style="display: none;"></div><div style="display: none;"></div><div style="display: block;"></div></div></div>
<script>
(function(){
var tabView = new YAHOO.widget.TabView('environmentNavigation');
// We add an entry under the ApplicationPortalUtils.defaultNavItem key to represent the default secondary navigation
// item (tab) to be displayed for the current top-navigation item ("app"). It will always be the first item in the list.
var navItemDefaultContent = {};
navItemDefaultContent[ApplicationPortalUtils.defaultNavItem] = {};
navItemDefaultContent[ApplicationPortalUtils.defaultNavItem]['url'] = '\/portal.bg?appian_environment=apps&%24p=67';
navItemDefaultContent[ApplicationPortalUtils.defaultNavItem]['index'] = 0;
navItemDefaultContent['myDash'] = {};
navItemDefaultContent['myDash']['url'] = '\/portal.bg?appian_environment=apps&%24p=67';
navItemDefaultContent['myDash']['index'] = '0';
navItemDefaultContent['myApp'] = {};
navItemDefaultContent['myApp']['url'] = '\/portal.bg?appian_environment=apps&%24p=86';
navItemDefaultContent['myApp']['index'] = '1';
navItemDefaultContent['myPermits'] = {};
navItemDefaultContent['myPermits']['url'] = '\/portal.bg?appian_environment=apps&%24p=88';
navItemDefaultContent['myPermits']['index'] = '2';
navItemDefaultContent['allPermits'] = {};
navItemDefaultContent['allPermits']['url'] = '\/portal.bg?appian_environment=apps&%24p=85';
navItemDefaultContent['allPermits']['index'] = '3';
navItemDefaultContent['myDetails'] = {};
navItemDefaultContent['myDetails']['url'] = '\/portal.bg?appian_environment=apps&%24p=53';
navItemDefaultContent['myDetails']['index'] = '4';
Environment.Navigation.afterContentLoad = function(content) {
// #39204: Show main content after we finished loading everything to avoid flickering.
$("#mainContent").show();
};
/**
* Navigates into a new tab in the designer portal environment.
*
* #param {String} navToken The URL identifier corresponding to the secondary navigation item. Optionally it
* can also contain the content url to load. The format in the latter case is: url_identifier[;content].
* The content url is expected to be properly URL encoded.
* #param {String} pageId (optional) The URL identifier corresponding to the page to show.
*/
Environment.Navigation.goTo = function(navToken, pageId) {
// #37674: the tabView component does not provide a way to get the number of tabs,
// so try and retrieve the second one. If it does not exist, hide the component.
if (!tabView.getTab(1)) {
$('#environmentNavigation').hide();
}
var currentState = YAHOO.util.History.getCurrentState(ApplicationPortalUtils.navItemKey);
if (navToken === currentState) {
var navConfig = {};
var contentIndex = navToken.indexOf(';');
if (contentIndex < 0) {
navConfig.navItemId = navToken;
} else {
navConfig.navItemId = navToken.substring(0, contentIndex);
navConfig.content = navToken.substring(contentIndex + 1);
}
// Check if the nav item is valid. If it's invalid, it will try to default to
// the application's default nav item.
if (!navItemDefaultContent[navConfig.navItemId]) {
if (!navItemDefaultContent['system.defaultitem']) { // The application itself is either invalid or it might not have any nav items.
// The app doesn't have any content to load, so we manually need to invoke the
// "afterContentLoad" callback.
Environment.Navigation.afterContentLoad();
return;
}
var errorCallback = function() {
asi.alert('The specified page is not available.');
};
navConfig.navItemId = 'system.defaultitem';
}
tabView.set('activeIndex', navItemDefaultContent[navConfig.navItemId].index);
if (pageId) {
backgroundAction('/portal.do?$p=' + pageId, null, errorCallback);
} else if (!navConfig.content || StringUtils.isBlank(navConfig.content)) {
backgroundAction(navItemDefaultContent[navConfig.navItemId].url, null, errorCallback);
} else {
backgroundAction(navConfig.content, null, errorCallback);
}
} else {
YAHOO.util.History.navigate(ApplicationPortalUtils.navItemKey, navToken);
}
};
$('#environmentNavigation li').click(function(){
var navItem = this.getAttribute(ApplicationPortalUtils.navItemKey);
Environment.Navigation.goTo(navItem);
});
})();
</script>
<div id="environmentTitlebar">
<div style="position:relative">
<div id="inlineConfirmMessage" onclick="STATUS.hide();" title="Click to hide message" class="" style="display: none;">Inline confirmation message text goes here</div>
</div>
<div id="pageTitle">My Details</div>
<div id="pageContext"></div>
<div id="breadcrumb"></div>
<div class="links">
<div id="optionsToggleContainer" style="">
Actions
</div>
</div>
<div id="pageOptionsMenu" class="yuimenu yui-module yui-overlay" style="z-index: 1; position: absolute; visibility: hidden; left: -10000px; top: -9999.41px;"><div class="bd"><ul class="first-of-type"><li class="yuimenuitem first-of-type" id="yui-gen3" groupindex="0" index="0">Bookmark this page</li></ul></div><div class="yui-menu-shadow"></div></div>
</div>
<div id="environmentContent" lasthref="/portal.bg?appian_environment=apps&%24p=53" class="">
<div class="asiPortalPageHeader"><h1>My Details</h1>
</div>
<div class="asiToolbar" id="portalPageToolbar" style="display: none;">
<input id="secretPageName" type="hidden" value="My Details">
</div>
<div style="float: left; width: 70%;" id="leftColumn" class="portletColumn"><div id="portletContainer_178">
<a name="178"></a>
<div class="portlet portletPlain">
<div class="portletHeader viewerMode">
</div>
</div>
<div id="portletContainer_224">
<a name="224"></a>
<div class="portlet portletPlain">
<div class="portletHeader viewerMode">
</div>
<div class="portletBody">
<div class="portletError" id="portletError_224" style="display:none;"></div>
<div class="portletMessage" id="portletMessageBar_224" style="display:none;"></div>
<div id="miniWebForm_224" class="mini">
<div id="miniWebContent_224" style="display: none"><p><strong><font size="3">Update My User Profile</font></strong></p>
<p><em>You can update your user contact details using this function.<br></em></p></div>
<iframe title="Web channel content" style="width: 100%; height: 35px;" frameborder="0" id="miniWebIframe_224" src="/suite/p_mini/viewMiniContent.do?chid=224&appian_environment=apps"></iframe>
</div>
</div>
</div>
</div>
<div id="portletContainer_232">
<a name="232"></a>
<div class="portlet portletPlain">
<div class="portletHeader viewerMode">
</div>
<div class="portletBody">
<div class="portletError" id="portletError_232" style="display:none;"></div>
<div class="portletMessage" id="portletMessageBar_232" style="display:none;"></div>
<div id="miniWebForm_232" class="mini">
<div id="miniWebContent_232" style="display: none"><p><strong><font size="3">Change My User Password </font></strong></p>
<p><em>You can reset your MyMines Online password using this function.</em><br></p></div>
<iframe title="Web channel content" style="width: 100%; height: 35px;" frameborder="0" id="miniWebIframe_232" src="/suite/p_mini/viewMiniContent.do?chid=232&appian_environment=apps"></iframe>
</div>
</div>
</div>
</div>
<div id="portletContainer_108">
<a name="108"></a>
<div class="portlet portletPlain">
<div class="portletHeader viewerMode">
</div>
<div class="portletBody">
<div class="portletError" id="portletError_108" style="display:none;"></div>
<div class="portletMessage" id="portletMessageBar_108" style="display:none;"></div>
<div id="miniWebForm_108" class="mini">
<div id="miniWebContent_108" style="display: none"><p> </p>
<p><font size="5"><strong>Authorised holder representative (AHR) details <br></strong></font></p>
<hr>
<p></p>
<p></p></div>
<iframe title="Web channel content" style="width: 100%; height: 59px;" frameborder="0" id="miniWebIframe_108" src="/suite/p_mini/viewMiniContent.do?chid=108&appian_environment=apps"></iframe>
</div>
</div>
</div>
</div>
</div>
<div style="float: right; width: 29%;" id="rightColumn" class="portletColumn"><div id="portletContainer_112">
<a name="112"></a>
<div class="portlet portletDefault">
<div class="portletHeader">
I want to...
</div>
<div class="portletBody">
<div class="portletError" id="portletError_112" style="display:none;"></div>
<div class="portletMessage" id="portletMessageBar_112" style="display:none;"></div>
<div id="miniWebForm_112" class="mini">
<div id="miniWebContent_112" style="display: none"><p>Contact the helpdesk</p>
<p>Open MyMinesOnline help<br></p></div>
<iframe title="Web channel content" style="width: 100%; height: 30px;" frameborder="0" id="miniWebIframe_112" src="/suite/p_mini/viewMiniContent.do?chid=112&appian_environment=apps"></iframe>
</div>
</div>
</div>
</div>
</div>
<br style="clear: both;">
<div style="clear: both; visibility: hidden;">.</div></div>
<script type="text/javascript">
(function(){
function updateCounter(containers, count) {
if(count > 0) {
containers.html(" ({0})".supplant(count));
} else {
containers.html("");
}
}
var tasksCount = parseInt('2');
var notificationsCount = parseInt('0');
var tasksSpan = $("#environmentHeader span.taskCount").add("#environmentNavigation span.taskCount");
var alertsSpan = $("#environmentHeader span.notificationCount").add("#environmentNavigation span.notificationCount");
updateCounter(tasksSpan, tasksCount);
updateCounter(alertsSpan, notificationsCount);
})();
</script>
<div style="clear:both; visibility:hidden;"> </div>
</div>
</div>
<iframe id="yui-history-iframe" style="display:none;" src="/suite/portal/blank.jsp" title="Background processing frame. No displayed content."></iframe>
<input id="yui-history-field" type="hidden">
<script>
(function initializeHistory(){
var initialTopNavViewState = YAHOO.util.History.getBookmarkedState(ApplicationPortalUtils.topNavKey);
if (StringUtils.isBlank(initialTopNavViewState)) {
// if no bookmarked state is available then use the top-navigation item determined by
// ApplicationsPortalEntryPoint as the default state; 'system.tasks' is used as last-resource
// fallback -it would only be used if the requested top-navigation item is invalid or not
// available; in which case we already present an error page.
var topNavItemId = 'myminesonline';
initialTopNavViewState = StringUtils.isBlank(topNavItemId) ? 'system.tasks' : topNavItemId;
}
// The registration of the application needs to happen before the registration of the
// tab navigation. When changing apps, we have to do a "multinavigate" to update
// both status, the status of the app and the navigation and YUI will trigger
// both of them. However, we just need to execute the application status change.
YAHOO.util.History.register(ApplicationPortalUtils.topNavKey, initialTopNavViewState, ApplicationPortalUtils.loadTopNavigation);
var initialNavItemState = YAHOO.util.History.getBookmarkedState(ApplicationPortalUtils.navItemKey) || ApplicationPortalUtils.defaultNavItem;
YAHOO.util.History.register(ApplicationPortalUtils.navItemKey, initialNavItemState, function(navId){
Environment.Navigation.goTo(navId);
});
YAHOO.util.History.onReady(function executeWhenPageIsFinishedLoading() {
// This function gets triggered after login or after a full page refresh.
// In the first case, there will not be a bookmarked state, we just need to go
// to the "initialNavItemState".
// In the second case, there might be a bookmarked state, if so, navigate to
// that state.
var bookmarkedTopNavState = YAHOO.util.History.getBookmarkedState(ApplicationPortalUtils.topNavKey);
if (StringUtils.isBlank(bookmarkedTopNavState)) {
Environment.Navigation.goTo(initialNavItemState);
} else {
ApplicationPortalUtils.loadTopNavigation(bookmarkedTopNavState);
}
});
YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");
})();
</script>
<div id="footer">
19.3.151 ©2003-2021 Queensland Government
</div>
<script type="text/javascript">
document.body.onclick= function (evt) {
evt = evt || event;
var target = evt.srcElement || evt.target;
try{ DATETIME.hideAll(target); } catch(e){}
try { hideAllReportPalettes(target, true); } catch(e){}
try{ DROPDOWN.hideAll(); } catch(e){}
try{ if(!(target.id in set('formPropertiesPaneLink','formPropertiesPaneImg'))){$("#formPropertiesPane").hide();}} catch(e){}
}
document.onmousedown = function (e) {
try { DIALOG.pick(e); } catch(e){}
}
document.onmousemove = function (e) {
try { DIALOG.move(e); } catch(e){}
}
document.onmouseup = function (e) {
try { DIALOG.drop(e); } catch(e){}
}
document.onmouseover = document.onmouseout = function () {
window.status = '';
return true;
}
window.onresize = function(){
if (AUTOCOMPLETE.pointer){ AUTOCOMPLETE.pointer.placeSuggestionGrid(); }
}
function hideLayers() {
try { STATUS.hide(); } catch(e){}
try { DIALOG.hide(); } catch(e){}
try { DATETIME.hideAll(); } catch(e){}
try { PICKER.hideAll(); } catch(e){}
asi.removeAlert();
}
document.onkeydown = function(e) {
e = e || event;
switch (e.keyCode) {
case ESC_KEY: hideLayers(); break;
case ENTER_KEY:
try { autoClick(getObject('asiAlertOK')); } catch(e){}
break;
}
return true;
}
function onfocus() {
if ((typeof processModelerLegacy != 'undefined' && processModelerLegacy.closed == true) ||
(typeof processModelerDesign != 'undefined' && processModelerDesign.closed == true)) {
if (window.PROCESS_MODEL_ID) {
backgroundPage("/process/unlockProcessModel.none?processModelId="+window.PROCESS_MODEL_ID);
} else if (window.PROCESS_ID) {
backgroundPage("/process/unlockProcessModel.none?processId="+window.PROCESS_ID);
}
document.body.onfocus=null;
}
if (typeof processModelerLegacy == 'undefined' && typeof processModelerDesign == 'undefined') {
document.body.onfocus=null;
}
}
</script>
<iframe src="javascript:''" id="masterapp" tabindex="-1" style="position: absolute; width: 0px; height: 0px; border: none;"></iframe><div aria-hidden="true" style="display: none;"></div><div class="appian-indicator-message" style="display: none;" aria-hidden="true"><span class="GE4QWF-BK-"><span class="GE4QWF-BJ-">Working...</span></span> <span class="GE4QWF-BL-">Working...</span></div><div style="position: absolute; height: 1px; width: 1px; top: -1000px; left: -1000px;"><span class="ygtvtm"> </span><span class="ygtvtmh"> </span><span class="ygtvtp"> </span><span class="ygtvtph"> </span><span class="ygtvln"> </span><span class="ygtvlm"> </span><span class="ygtvlmh"> </span><span class="ygtvlp"> </span><span class="ygtvlph"> </span><span class="ygtvloading"> </span></div></body>
You need to switch to the <frame> first, and then find the element.
frame = driver.find_element_by_id("fContent")
driver.switch_to.frame(frame)
xpath = "//div[#id='environmentNavigation']//li/a[contains(., 'All permits')]"
tab = wait.until(EC.element_to_be_clickable((By.XPATH, xpath))
tab.click()
try to click with javascript:
import time
time.sleep(3)
el = driver.find_element_by_xpath('//li[#nav="allPermits"]')
driver.execute_script("arguments[0].click();", el)
Related
With the following url and soup, I have the following and I seek to webscrape the Subdivision Information Section. I have copied the html portion for one house below:
house_url = 'https://www.har.com/homedetail/2701-main-st-1910-houston-tx-77002/15331551'
house_response = requests.get(url=house_url, headers=your_header)
house_soup = BeautifulSoup(house_response.text, 'html.parser').find('div', {'class':'pt-2 pb-2 mr-4 pr-md-5 ml-4 pl-md-5'})
Subdivision Section HTML
<div id="subDivisonInfo" class="lazy" data-contentname="subdivision-facts"><div class="mb-5 pb-5 border-bottom border-color--cement_light">
<h2 tabindex="0">Subdivision Facts</h2>
<a class="font_weight--bold font_size--large mr-4" href="/geomarketarea/100_midtown---houston">View Neighborhood Profile </a>
<div class="mb-5 mt-4 pb-3">
<a href="/geomarketarea/100_midtown---houston">
<div class="mb-3 border_radius--round image" style="height: 360px; width: 100%; background-size: cover; background-repeat: no-repeat; background-position: center center; background-image: url("https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/path-1+0000ff-0.45+0000ff-0.45(u%7CstDfobeQnCbExAhAdCx%40xBXvDDlA%40lMF%7ECBvBEhJOVAnDo%40dDiClByCpCkEh%60%40sv%40zx%40vi%40rGhEx%40jAXF%5ElAB%60%40Bx%40Dx%40%3FfBPlBLxA%60%40fL%5EtMNhGFlBJdEDxAHlANdCHbBPpDDpA%3FhDFzE%40xB%40zADbBa%40sB%5Bk%40q%40gA%7DA%7DAw%40k%40yAcAqBwAyAgAiBuAyCyBoBuAmA%7B%40u%40i%40%7BBaB%7BC%7BAsBc%40kF%5D%7BE%3F%7BDHqCIuESk%40%3FCvCAv%40%3FtCJ%7EK%3FlA%7DLB%3F%7B%40yJB_K%40_E%3FwJ%40mX%40yA%40sIFgM%40%3FkDOcCm%40_IeBgG%3F%3FaAyDs%40_EWgBGsASuDQiNGoNKwJ%3F%3FQuH%7EClJjCfG)/auto/651x360?access_token=pk.eyJ1IjoiaGFyZGV2ZXJpY2siLCJhIjoiY2sxZ3FuNWJpMDFtbDNjbDJ0bnJnbnpkdyJ9.byj8yrbalnyCw4u9TNwYuA");">
<img class="img-fluid img-loader" src="https://content.harstatic.com/img/common/loading1.gif" style="display: none;">
</div>
<script type="text/javascript">
/*! domready (c) Dustin Diaz 2014 - License MIT */
;!function(e,t){"undefined"!=typeof module?module.exports=t():"function"==typeof define&&"object"==typeof define.amd?define(t):this.domready=t()}(0,function(){var e,t=[],o="object"==typeof document&&document,n=o&&o.documentElement.doScroll,d=o&&(n?/^loaded|^c/:/^loaded|^i|^c/).test(o.readyState);return!d&&o&&o.addEventListener("DOMContentLoaded",e=function(){for(o.removeEventListener("DOMContentLoaded",e),d=1;e=t.shift();)e()}),function(e){d?setTimeout(e,0):t.push(e)}});
</script>
<script type="text/javascript">
domready(function() {
HARMap.load().then(function(module) {
var componentId = 'image24906579';
var polygon = 'POLYGON((-95.372842651 29.762188072,-95.373816894 29.761474216,-95.374191992 29.76101599,-95.374483311 29.760352652,-95.374609142 29.759738202,-95.374640089 29.758819359,-95.374647572 29.758426112,-95.374691499 29.756117694,-95.374706659 29.75532102,-95.3746799 29.754718062,-95.374599516 29.752906601,-95.374594347 29.752790096,-95.374351409 29.751909331,-95.373661419 29.751078253,-95.372887724 29.750528187,-95.371869687 29.74980439,-95.362970840876 29.744465093909,-95.369806756 29.735213416,-95.370819903 29.733833779,-95.371197558 29.733537028,-95.371239769 29.733411918,-95.371629671 29.733245349,-95.371804383 29.73323255,-95.372090663 29.733211576,-95.372379167 29.733175792,-95.372896911 29.733184661,-95.373448298 29.733085864,-95.373897555 29.73302357,-95.376020952 29.732848991,-95.378367141 29.732692501,-95.379698574 29.732605591,-95.380251649 29.73256989,-95.381236514 29.732506316,-95.381686127 29.732477294,-95.382077218 29.732432106,-95.382753475 29.732353969,-95.383254109 29.732299798,-95.384141891 29.732214015,-95.384547373 29.732184995,-95.385401694 29.732177061,-95.386504599 29.7321448,-95.387113815 29.732128476,-95.38757473 29.732116124,-95.388065951 29.732085741,-95.387487144 29.732263493,-95.387266095 29.732397447,-95.386907035 29.732649085,-95.386438833 29.733120089,-95.386221661 29.733399038,-95.385875385 29.733846224,-95.385438799 29.734415138,-95.38508092 29.734869849,-95.384651063 29.735397347,-95.384037746 29.736172341,-95.383612227 29.736729284,-95.383311768 29.737122539,-95.383099783 29.737389038,-95.382608073 29.738007194,-95.382145211 29.738793482,-95.381972784 29.739372769,-95.381824272 29.740550975,-95.381818116 29.741650627,-95.381867014 29.742586972,-95.381820616 29.743316543,-95.38172399 29.744387766,-95.381721351 29.744610716,-95.382483057 29.744631286,-95.382763059 29.744636527,-95.383509646 29.74463557,-95.385588363 29.744584135,-95.385979746 29.744575193,-95.386003821 29.746807942,-95.385699411 29.746810253,-95.385718338 29.748696241,-95.385725089 29.750624573,-95.385732125 29.75158054,-95.385735183 29.753459289,-95.385748282 29.757531403,-95.385758824 29.757976236,-95.385799269 29.75968271,-95.385808634 29.76196431,-95.384952318 29.761964306,-95.384292125 29.762037035,-95.382689529 29.76226967,-95.381370964 29.762781324,-95.381373603 29.762782609,-95.380443808 29.763114063,-95.379476498 29.763374528,-95.378959294 29.763485938,-95.378540344 29.763528353,-95.377633441 29.763629227,-95.375180147 29.763724096,-95.37270141 29.763764494,-95.370824522 29.763815179,-95.370818039 29.76381558,-95.369274785 29.76391082,-95.371101581 29.763114639,-95.372416403 29.762414919,-95.372842651 29.762188072))';
var node = $('.' + componentId).removeClass(componentId);
// var result = module.StaticMap.custom.withPolygon(node.width(), node.height(), polygon)
// result.backgroundImage(node);
var result = module.StaticMap.custom.withPolygon(node.width(), node.height(), polygon)
result.backgroundImage(node);
/*var geometry = module.geometry;
var points = geometry.pointsFromWKT(polygon);
//console.log(points);
if(points.length > 100) { points = geometry.simplifyPolygon(points, 0.0001); }
if(points.length > 100) { points = geometry.simplifyPolygon(points, 0.001); }
//console.log(points);
var encString = geometry.encodePath(points);
var width = node.width();
var height = node.height();
if(!width) { console.error('width cannot be empty!'); }
if(!height) { console.error('height cannot be empty!'); }
var path = encodeURIComponent("weight:1|fillcolor:blue|enc:" + encString);
var url = "/api/staticmap?size="+ width +"x"+ height +"&path="+ path + "&client=gme-houstonrealtorsinformation";
// alert(url);
//$(node).html('<a class="pointer" href="'+url+'" id="hoodMapStaticLink"></a><img />');
var image = new Image();
image.onload = image.onerror = function() { node.find('img').remove(); }
image.src = url;
$(node).css('background-image', 'url(' + url + ')');*/
});
});
</script> </a>
</div>
<h3 class="mt-5 pb-3" tabindex="0">Facts (Based on Active listings)</h3>
<div class="row">
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Market Area Name</div>
<div class="font_size--large font_weight--regular">Midtown - Houston</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Home For Sales</div>
<div class="font_size--large font_weight--regular">104</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average List Price</div>
<div class="font_size--large font_weight--regular">$428,844</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average Bedrooms</div>
<div class="font_size--large font_weight--regular">2.27</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average Baths</div>
<div class="font_size--large font_weight--regular">2.07</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average Sqft</div>
<div class="font_size--large font_weight--regular">1,873</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average Price/Sqft</div>
<div class="font_size--large font_weight--regular">$236.48</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Home For Lease</div>
<div class="font_size--large font_weight--regular">96</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average Lease</div>
<div class="font_size--large font_weight--regular">$2,396</div>
</div>
<div class="col-md-4 col-6 mb-4">
<div class="font_weight--bold font_size--small_extra">Average Lease/Sqft</div>
<div class="font_size--large font_weight--regular">$1.76</div>
</div>
</div>
</div>
</div>
However, whenever I use beautifulSoup to get the text such as "Average List Price:$428,844", This is the output I get:
house_soup.find('div',{'id':'subDivisonInfo'}).find('div',{'class':'row'}).findAll('div',{'class':'col-md-4 col-6 mb-4'})[0].getText()
'\n-----------\n-----------\n'
I am not sure why it is returning this string instead of the actual text?
The required data is loaded from external source via AJAX.So you have to use API url instead.
import requests
from bs4 import BeautifulSoup
api_url= 'https://www.har.com/api/getSubdivisionFacts/15331551'
req=requests.get(api_url).text
#print(req)
soup= BeautifulSoup(req,'lxml')
price = soup.select_one('[class="col-md-4 col-6 mb-4"] > div:-soup-contains("Average List Price")').find_next_sibling('div')
print(price.text)
Output:
$428,844
Because there is a script executed that gets the data when you open the url in the browser. Try performing a get request in python and check the html contents. The initial html does not contain the details you are looking for such as "Average Listing Price".
I am trying to get the html code of one marketplace, I am getting the correct code for one category but for another one I am getting wrong result.
For this one
k = requests.get('https://www.skroutz.gr/plus-deals').text
soup1=BeautifulSoup(k,'html.parser')
soup1
I am getting the correct html code and I can process the data but for the following link i am getting less html code and there is now info about the product inside.
k = requests.get('https://www.skroutz.gr/c/40/kinhta-thlefwna.html').text
soup=BeautifulSoup(k,'html.parser')
soup
Output
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en-US"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en-US"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-US"> <!--<![endif]-->
<head>
<title>Please Wait... | Cloudflare</title>
<meta charset="utf-8"/>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<meta content="IE=Edge" http-equiv="X-UA-Compatible"/>
<meta content="noindex, nofollow" name="robots"/>
<meta content="width=device-width,initial-scale=1" name="viewport"/>
<link href="/cdn-cgi/styles/cf.errors.css" id="cf_styles-css" rel="stylesheet"/>
<!--[if lt IE 9]><link rel="stylesheet" id='cf_styles-ie-css' href="/cdn-cgi/styles/cf.errors.ie.css" /><![endif]-->
<style>body{margin:0;padding:0}</style>
<!--[if gte IE 10]><!-->
<script>
if (!navigator.cookieEnabled) {
window.addEventListener('DOMContentLoaded', function () {
var cookieEl = document.getElementById('cookie-alert');
cookieEl.style.display = 'block';
})
}
</script>
<!--<![endif]-->
<script>
//<![CDATA[
(function(){
window._cf_chl_opt={
cvId: "2",
cType: "managed",
cNounce: "84571",
cRay: "724b4343a9c4152e",
cHash: "fe638ea0b43499b",
cUPMDTk: "\/c\/40\/kinhta-thlefwna.html?__cf_chl_tk=SyBbHJlHzS.xDpnxJdXeTIBNmKGSVY9Caf6BU5YW6xE-1656805606-0-gaNycGzNBz0",
cFPWv: "b",
cTTimeMs: "1000",
cLt: "n",
cRq: {
ru: "aHR0cHM6Ly93d3cuc2tyb3V0ei5nci9jLzQwL2tpbmh0YS10aGxlZnduYS5odG1s",
ra: "cHl0aG9uLXJlcXVlc3RzLzIuMjYuMA==",
rm: "R0VU",
d: "MFxIKPp9sia0pudoUteuGKwmEJZnwrwbUU7R6o3bLbmRQdKUSifFGDKIWAthmI25tWLGCJvkxJ/ZSXohN4X7NLhi1X31Fa3HI/KIaiMyh8YXFbroUVZul9D5Y0Hxgy3uYhvKQWMzzsfJA0wJ3OWZCF2SCCYvYhqZeaVPccnVLdSfk0r1+/iOoRZlTpwKzHg1y8avQMw3jpGpm4AvsDclXglM3x1j0hmlFWCig7J2b1QPfPUB1n7jUOL7angCdkUPRolkIzbpbiv1EBnFvj8LTKjERnDHfL9FMw/kobs+wwFcHik9T3fBJA6zpy3pMCiJCMv8yXAAnbmICUswEwNMGEqj2XSYaae1wYLwVRfku7hcs5p1SULPSvG6Tdnw3KBFaN8G3LCzuPXMCIecb0shm/WJQLFiQJZ3vkqH4pYgVzU+dy0RKpmpFdPX/oJcvcCexMG9PQS+5DmKbEqSaMJ0o4MS3lydhg/0CB98601f/gQpLlOvwGQgmpZA0dQNsoJ4qdk/zkPIsonkBETn8ymsyUWZTYjARpB5oPl2Pb/jIBaTEbYiI/q0AkBC4NL3AHZTpJimOCbg+Qo1qW2qMjIJ4sguHuVn1sXfdD61k0x5AS29MSDKIL7TNcIybM223qnleOlFMwBhOYuRt5kbhi0iCQ==",
t: "MTY1NjgwNTYwNi45OTUwMDA=",
m: "jz0GZxi5IN9yD0ZMzRvqHS7iO3DUD67nnR9aWi8akek=",
i1: "yKKkb4Pl9MdAGpv3ff55sw==",
i2: "0V/b+SP8SYiGm6Ql5jqhjg==",
zh: "zMLZU0ozMixiusF5YQ59SCEM/iph9RYq7XDo619EjZk=",
uh: "xaa5dII6Z3KyYGzGAu/zTXOfAYzLW3WlpO4dxW/Wc8c=",
hh: "SbqW99632Mb3TCb6zbuLigmv9PVrnmEea13QmnYx5Y4=",
}
};
}());
//]]>
</script>
<style>
#cf-wrapper #spinner {width:69px; margin: auto;}
#cf-wrapper #cf-please-wait{text-align:center}
.attribution {margin-top: 32px;}
.bubbles { background-color: #f58220; width:20px; height: 20px; margin:2px; border-radius:100%; display:inline-block; }
#cf-wrapper #challenge-form { padding-top:25px; padding-bottom:25px; }
#cf-hcaptcha-container { text-align:center;}
#cf-hcaptcha-container iframe { display: inline-block;}
#keyframes fader { 0% {opacity: 0.2;} 50% {opacity: 1.0;} 100% {opacity: 0.2;} }
#cf-wrapper #cf-bubbles { width:69px; }
#-webkit-keyframes fader { 0% {opacity: 0.2;} 50% {opacity: 1.0;} 100% {opacity: 0.2;} }
#cf-bubbles > .bubbles { animation: fader 1.6s infinite;}
#cf-bubbles > .bubbles:nth-child(2) { animation-delay: .2s;}
#cf-bubbles > .bubbles:nth-child(3) { animation-delay: .4s;}
</style>
</head>
<body>
<div id="cf-wrapper">
<div class="cf-alert cf-alert-error cf-cookie-error" data-translate="enable_cookies" id="cookie-alert">Please enable cookies.</div>
<div class="cf-error-details-wrapper" id="cf-error-details">
<div class="cf-wrapper cf-header cf-error-overview">
<h1 data-translate="managed_challenge_headline">Please wait...</h1>
<h2 class="cf-subheadline"><span data-translate="managed_checking_msg">We are checking your browser...</span> www.skroutz.gr</h2>
</div>
<div class="cf-section cf-highlight cf-captcha-container">
<div class="cf-wrapper">
<div class="cf-columns two">
<div class="cf-column">
<div class="cf-highlight-inverse cf-form-stacked">
<form action="/c/40/kinhta-thlefwna.html?__cf_chl_f_tk=SyBbHJlHzS.xDpnxJdXeTIBNmKGSVY9Caf6BU5YW6xE-1656805606-0-gaNycGzNBz0" class="challenge-form managed-form" enctype="application/x-www-form-urlencoded" id="challenge-form" method="POST">
<div id="cf-please-wait">
<div id="spinner">
<div id="cf-bubbles">
<div class="bubbles"></div>
<div class="bubbles"></div>
<div class="bubbles"></div>
</div>
</div>
<p data-translate="please_wait" id="cf-spinner-please-wait">Please stand by, while we are checking your browser...</p>
<p data-translate="redirecting" id="cf-spinner-redirecting" style="display:none">Redirecting...</p>
</div>
<input name="md" type="hidden" value="IwzwByLaPyYwh36ds_B76pH5fbjsm4NPLcrfOyVKp4k-1656805606-0-ATjH4PthZIQnlHja_TD2k3GIpJNvZi83t0ImbV0HYerX3pLXRLzqVYaRg_jJnr-ENIDFSkm2yG4ucsXrIj2kFquA7Ko4B40ctfjPfq93KAuO2HKoglP7QsaBaAwi3M-psOfnAbR48_o8kIFryXMdm6fJxGT8XpMh4LukCG0MavaJDWjYYiZcHHX82oSF7rx5_LnOgEkx0xkLtZZseZkhzqTfzzJ0S9wKzO9ZZdQMKxRxMIXWn36p3IezexUmZFlfbNtTFuETI0mWGSoTodXSiebeJasF-Ug2dnksRfhCQ1tsLun1XkVrbB5FauyBoa1Lh2-j6k3iW59xN6wsekKZcTrSaq03kn-bEod25lpVvQoe6u0wMmNYbBNWUtn4GER9CxWsDlUAXAwCp-BJAD-lHiJzAuBAmygbwFLRsoOcKOzUqtdQXNMX852hbTsSeTEw8a8bYxj-rHT4-d4zZDHGAw-dWKUAzVrtVSJLKlnRbknZ8BgT4FNnHF3Wwoo6JJxpoyYrrpMi4X27dgBkyymEQ0t1q7LXO_NSBxZIs33DM3hdiBMBHa69ZlFv92IKf-g6pnJnJj1QSlo5kVBTEd_wDswWTzLO6LmFz9VmMbGYTPPYbSFlP_b1VipLLI2DA4UVIOvb_7-alRtQjQQVZXFlkQYREd2J2EKtjzaOdMDKB6PgldFFeAOb97nCukF9UBBXHBAIATvR05AMvKt3LdBeL_3VDoyZe4Gnl8gbzlUTNP4OQ-o8ZEGcPC86WqWj5t2pSHw9XLxDFgR4IT7uYQOCY0cDmNe-BcbWz71ELBDGUXoyu7snXR_nMh6E3b87YNxVRSzeQ5JMrxajndJOfG_Oe0HSFF2SXFU_ahvhlY_GAY9TqexHH0pYzoVCJUtrkU8eTQ"/>
<input name="r" type="hidden" value="DUXMrZguXrr5SKxL5gb8bc9rgvwFZTJBMi4FVb0iz94-1656805606-0-AWxS7hG0CDsoq8Hfnn/fAlbcwDr533szKw8waJNidRmjag4uyqPCsquvtrdjXbzXFP39PakxrWmNVDcKmdXQ6S9o9TGKWaXg537pbNvR73prQvU1eXhXCkbjf86u4b88W0acULgkpL9h+5tRLelwypJ3QwI2X/MfTod2V2drUXQ5h0peLqbcO0HTqMTvXgwUSQapbHaW8ZiQp+mGupb30Pu8YMKTXRGgvJWilv1F+WhpyprJaNOA86hfIlIolBHItxli/EZHW8IR4/GmMlFowX11GPibk8OLHZ+YizRjmdnALqh/AraZFv8GgRwerfHXrZvwka6KqlggzN77KL1q0JhnG1B0oAef8kpOr+yxxp2+cLCiJV8UkCTa96xVAsIwsz1lamCKGqJHaoFVLadytpHWkWQ+Mfqr2/a4tl9ivB6K6bB7qZBzneFusiSOXfwrSsgeXJ6aLNUzuYtMR8wpEVVkiakRpsFVXKIJOzD3KgFyCAfMCd8F2cktMc1+IasYMPlLuE96aqHqQFOoZoNCKOkxIjC35w3SGYgVUw7GOwGtvt08Q6mHns9C9PpRSxsIXUS1jMvQdRIW1tI3lBa1f/9u+u326qXb43+Hnk1F5nuIkXir6CkZKz3HFbAKKJis8rEyI7V0XCKpM/dd0n0EE6H75L0ogVgyQ0YtzxF03NvTdbO4pVLIHoWveMSVQHSFBHvJnVC7B5hhjoFVreOKh4mq3MAWM68jpdhYpv0lFNCSh50T+aCvcdXDCy78PqNQYl0C6jRfsFrGlkUxdLAN/UFwPNq/FzhwijK05TDkY0xN/eUQGoWxhDuCq4FMcukFHlHLMX9XomWLJV70XgP4OHxVarraKvzXTKDLVmKw04mNcVHVXR9syQmZnGWT9kSonL8Yqie6Z4K7JsMZIQuKFbVSLvvMvPsp5Ij9gNmGmexBcbxoQCoi4UivIg8WBtGu8D0BssU5QN8jTlcupcPqY+CsYFmvF3fX0CT3Vri46K6uxRDiXiVhAls7FnhjH1eFykshMQgDVZ04RopWa+sBGy/8FB2b7OI7kXgV0AaQTAkjiywNgKE93F7udAjXHjMYI4Z6MBwa2M8R3/CaC/6nfrCuI9JSopiPs7bXDjYXvVSwAUmaaWHHowg8F7xNbDWPRutBjaAauCqXLEMFYUs7NUyXwuvM+SqbV9T02Iukya848oEqMGX/pfrXcEP+BoXw/rL7PQ0J1NCB5leXQ4kJYmJpEvhsCi+3jklvpPgTxgmH66D5/dOF6EIUKlNO70Mk5Ft6aVEewLT/SWwXcyXjd5jXjLEyrG2PZN3oNFSMRFPLZqXDbwafxYjKHQoFHDKWSoESdTb6pO31v5kDzFdDF5wfy8Grr5tqYEiCQaiawPMEvbzZ/C0CbmZEvxxgii9UA/fNU6ZtvCXoljfao5b1tVh7ww0Bl3/KtCjj/zDcittuheaQaoBrAd1h0L1m1G/UmcXlRoJXthIRatelutU1voXttp097S8myV92G65vM+J5T+8q4yiFapkRYvwKRtp6spOaIqIEGh1VHGZAUZZFu2TtZRA1kVWFXof8d0krQvUly9QmxWAz4xHqIpedOtjc+0Sa+aX781jxvKzZ6YA9kWe78Z1VCUsv3h7vKUZ3uUD1mDt8xpZukiuCtU8fqH+8rPhEeKoAOTk03HrzvrjnUeplxjht6JOx0ZfkvFaUyjDjnL4Pr/R9uMe9V07Dl6aIj9HaQRtBfygajoSePZwAi7emffrLi8YPjvYctJCFyK/auNRJBIKj5nEeOUvKkKNmdA=="/>
<input name="vc" type="hidden" value="28e85100a980cbce13a010a21dbc0851"/>
<noscript class="cf-captcha-info" id="cf-captcha-bookmark">
<h1 data-translate="turn_on_js" style="color:#bd2426;">Please turn JavaScript on and reload the page.</h1>
</noscript>
<div class="cookie-warning" data-translate="turn_on_cookies" id="no-cookie-warning" style="display:none">
<p data-translate="turn_on_cookies" style="color:#bd2426;">Please enable Cookies and reload the page.</p>
</div>
<script>
//<![CDATA[
var a = function() {try{return !!window.addEventListener} catch(e) {return !1} },
b = function(b, c) {a() ? document.addEventListener("DOMContentLoaded", b, c) : document.attachEvent("onreadystatechange", b)};
b(function(){
var cookiesEnabled=(navigator.cookieEnabled)? true : false;
if(!cookiesEnabled){
var q = document.getElementById('no-cookie-warning');q.style.display = 'block';
}
});
//]]>
</script>
<div id="trk_captcha_js" style="background-image:url('/cdn-cgi/images/trace/captcha/nojs/h/transparent.gif?ray=724b4343a9c4152e')"></div>
</form>
<script>
//<![CDATA[
(function(){
var isIE = /(MSIE|Trident\/|Edge\/)/i.test(window.navigator.userAgent);
var trkjs = isIE ? new Image() : document.createElement('img');
trkjs.setAttribute("src", "/cdn-cgi/images/trace/managed/js/transparent.gif?ray=724b4343a9c4152e");
trkjs.id = "trk_managed_js";
trkjs.setAttribute("alt", "");
document.body.appendChild(trkjs);
var cpo=document.createElement('script');
cpo.type='text/javascript';
cpo.src="/cdn-cgi/challenge-platform/h/b/orchestrate/managed/v1?ray=724b4343a9c4152e";
window._cf_chl_opt.cOgUHash = location.hash === '' && location.href.indexOf('#') !== -1 ? '#' : location.hash;
window._cf_chl_opt.cOgUQuery = location.search === '' && location.href.slice(0, -window._cf_chl_opt.cOgUHash.length).indexOf('?') !== -1 ? '?' : location.search;
if (window._cf_chl_opt.cUPMDTk && window.history && window.history.replaceState) {
var ogU = location.pathname + window._cf_chl_opt.cOgUQuery + window._cf_chl_opt.cOgUHash;
history.replaceState(null, null, "\/c\/40\/kinhta-thlefwna.html?__cf_chl_rt_tk=SyBbHJlHzS.xDpnxJdXeTIBNmKGSVY9Caf6BU5YW6xE-1656805606-0-gaNycGzNBz0" + window._cf_chl_opt.cOgUHash);
cpo.onload = function() {
history.replaceState(null, null, ogU);
};
}
document.getElementsByTagName('head')[0].appendChild(cpo);
}());
//]]>
</script>
</div>
</div>
<div class="cf-column">
<div class="cf-screenshot-container">
<span class="cf-no-screenshot"></span>
</div>
</div>
</div>
</div>
</div>
<div class="cf-section cf-wrapper">
<div class="cf-columns two">
<div class="cf-column">
<h2 data-translate="why_captcha_headline">Why do I have to complete a CAPTCHA?</h2>
<p data-translate="why_captcha_detail">Completing the CAPTCHA proves you are a human and gives you temporary access to the web property.</p>
</div>
<div class="cf-column">
<h2 data-translate="resolve_captcha_headline">What can I do to prevent this in the future?</h2>
<p data-translate="resolve_captcha_antivirus">If you are on a personal connection, like at home, you can run an anti-virus scan on your device to make sure it is not infected with malware.</p>
<p data-translate="resolve_captcha_network">If you are at an office or shared network, you can ask the network administrator to run a scan across the network looking for misconfigured or infected devices.</p>
</div>
</div>
</div>
<div class="cf-error-footer cf-wrapper w-240 lg:w-full py-10 sm:py-4 sm:px-8 mx-auto text-center sm:text-left border-solid border-0 border-t border-gray-300">
<p class="text-13">
<span class="cf-footer-item sm:block sm:mb-1">Cloudflare Ray ID: <strong class="font-semibold">724b4343a9c4152e</strong></span>
<span class="cf-footer-separator sm:hidden">•</span>
<span class="cf-footer-item hidden sm:block sm:mb-1" id="cf-footer-item-ip">
Your IP:
<button class="cf-footer-ip-reveal-btn" id="cf-footer-ip-reveal" type="button">Click to reveal</button>
<span class="hidden" id="cf-footer-ip">213.7.17.251</span>
<span class="cf-footer-separator sm:hidden">•</span>
</span>
<span class="cf-footer-item sm:block sm:mb-1"><span>Performance & security by</span> Cloudflare</span>
</p>
<script>(function(){function d(){var b=a.getElementById("cf-footer-item-ip"),c=a.getElementById("cf-footer-ip-reveal");b&&"classList"in b&&(b.classList.remove("hidden"),c.addEventListener("click",function(){c.classList.add("hidden");a.getElementById("cf-footer-ip").classList.remove("hidden")}))}var a=document;document.addEventListener&&a.addEventListener("DOMContentLoaded",d)})();</script>
</div><!-- /.error-footer -->
</div>
</div>
<script>
window._cf_translation = {};
</script>
</body>
</html>
The website is loading data with an API. Here is the link: https://www.skroutz.gr/c/40/kinhta-thlefwna.json?page=1
I'm creating something where my flask backend will get the last added record from mysql, then the frontend will duplicate a div with that new information and display it to the user. It all works fine and as expected, but I don't get how to make it so that the previously duplicated divs contents won't have their values changed when a new record is added.
import copy
import pymysql
from flask import Flask, render_template, request, redirect, url_for, session, jsonify
conn = pymysql.connect(
host = 'localhost',
user = 'root',
password = '',
db = 'panel',
)
cur = conn.cursor()
app = Flask(__name__, template_folder = "templates")
rundupe = 1 # Debug
runpage = True # Debug
#app.route("/")
def index():
return render_template("index.html")
#app.route("/infected", methods=['GET', 'POST'])
def infected():
global rundupe
global runpage
if runpage:
#runpage = False
cur.execute("SELECT id FROM botinfo ORDER BY id DESC LIMIT 1")
res0 = cur.fetchone()[0]
print(res0)
cur.execute("SELECT ip FROM botinfo WHERE id = %s", (res0))
res1 = cur.fetchone()[0]
cur.execute("SELECT os FROM botinfo WHERE id = %s", (res0))
res2 = cur.fetchone()[0]
cur.execute("SELECT country FROM botinfo WHERE id = %s", (res0))
res3 = cur.fetchone()[0]
cur.execute("SELECT date FROM botinfo WHERE id = %s", (res0))
res4 = cur.fetchone()[0]
if res1 and res2 and res3 and res4:
return render_template("infected.html", newip = res1, newos = res2, country = res3, date = res4, id = res0, rundupe = rundupe)
return render_template("infected.html")
#app.route("/payloads")
def payloads():
return render_template("payloads.html")
#app.route("/db")
def database():
return render_template("database.html")
#app.route("/analytics")
def analytics():
return render_template("analytics.html")
#app.route("/cli")
def cli():
return render_template("cli.html")
#app.route("/security")
def security():
return render_template("security.html")
#app.route("/settings")
def settings():
return render_template("settings.html")
#app.route("/accepter", methods=["GET", "POST"])
def accept():
if request.method == "GET":
global rundupe
global runpage
ip = request.args.get("ip")
os = request.args.get("os")
country = request.args.get("country")
date = request.args.get("date")
if ip and os and country and date:
runpage = True
sql = "INSERT INTO botinfo (ip, os, country, date) VALUES (%s, %s, %s, %s)"
cur.execute(sql, (ip, os, country, date))
conn.commit()
rundupe += 1
return render_template("api.html")
app.run("127.0.0.1", 5000, debug = True)
Flask backend, first it gets some information in the accepter route from url parameters and then it saves that information into mysql and sends it to the user in the infected route.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght#500&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<title>Home</title>
</head>
<body onload="duplicate();" style="background-color: rgb(15, 15, 34);">
<div class="wrapper">
<div class="section">
<div class="top_navbar">
<div class="hamburger">
<a href="#">
<i class="fas fa-bars"></i>
</a>
</div>
</div>
</div>
<div class="sidebar">
<div class="profile">
<span class="icon"><i style="color: white;" class="fas fa-user-tie fa-3x"></i></span>
<h3>Visually</h3>
<p>System Admin</p>
</div>
<ul>
<li>
<a href="/">
<span class="icon"><i class="fas fa-home"></i></span>
<span class="item">Home</span>
</a>
</li>
<li>
<a href="/infected" class="active">
<span class="icon"><i class="fas fa-desktop"></i></span>
<span class="item">Infected</span>
</a>
</li>
<li>
<a href="/payloads">
<span class="icon"><i class="fas fa-scroll"></i></span>
<span class="item">Payloads</span>
</a>
</li>
<li>
<a href="/db">
<span class="icon"><i class="fas fa-database"></i></span>
<span class="item">Database</span>
</a>
</li>
<li>
<a href="/analytics">
<span class="icon"><i class="fas fa-chart-line"></i></span>
<span class="item">Analytics</span>
</a>
</li>
<li>
<a href="/cli">
<span class="icon"><i class="fas fa-terminal"></i></span>
<span class="item">Web CLI</span>
</a>
</li>
<li>
<a href="/security">
<span class="icon"><i class="fas fa-user-shield"></i></span>
<span class="item">Security</span>
</a>
</li>
<li>
<a href="/settings">
<span class="icon"><i class="fas fa-cog"></i></span>
<span class="item">Settings</span>
</a>
</li>
</ul>
</div>
</div>
<h1 style="text-align: center; color: white; margin-top: 2%; font-size: 50px;">Infected Machines</h1>
<div class="statsBox" style="margin-left: 415px; margin-top: 90px; width: 800px; height: 400px; overflow-y: auto;" id="machines">
<p style="text-align: center; font-size: 20px">Machines</p>
<div class="infectedBox" id="infectedBox" style="width: 793px; height: 90px; margin-top: 15px; cursor: pointer; background-color: rgb(2, 2, 31); display: none;">
<script type="text/javascript">
let i = 0;
let id = 0;
let num = 0;
const og = document.getElementById('infectedBox');
function duplicate() {
if('{{ rundupe }}') {
for(let i = 0; i < '{{ rundupe }}'; ++i) {
let clone = og.cloneNode(true);
clone.style.display = 'block';
clone.id = "duplicater" + ++i;
og.parentNode.appendChild(clone);
++num;
++id;
const number = document.querySelector(`#duplicater${i} #number`).textContent = `#${num}`;
const mainInfo = document.querySelector(`#duplicater${i} #mainInfo`).textContent = `Country: {{ country }}, OS: {{ newos }}, Date Captured: {{ date }}`;
const botInfo = document.querySelector(`#duplicater${i} #botInfo`).textContent = `Bot: {{ newip }}`;
console.log(number, mainInfo, botInfo);
}
}
}
</script>
<span class="icon"><i style="margin-left: 10px; margin-top: 12px;" class="fas fa-user fa-4x"></i></span>
<p id="botInfo" style="color: white; margin-top: -70px; margin-left: 100px; font-size: 20px;"></p>
<p id="mainInfo" style="color: white; margin-top: 12px; margin-left: 100px;"></p>
<p id="number" style="color: white; margin-top: -60px; margin-left: 700px; font-size: 60px;">#<script type="text/javascript">document.write(num);</script></p>
</div>
</div>
<script type="text/javascript">
let hamburger = document.querySelector(".hamburger");
hamburger.addEventListener("click", () => {
document.querySelector("body").classList.toggle("active");
})
</script>
</body>
</html>
html page to display the info.
from urllib.request import urlopen
from datetime import date
import urllib.request
import requests
import platform
import json
import sys
import re
today = date.today()
d1 = today.strftime("%m/%d/%Y")
url = 'http://ipinfo.io/json'
response = urlopen(url)
data = json.load(response)
country = data['country']
print(country)
pubip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
print(pubip)
os = platform.system()
print(os)
requests.get(f"http://127.0.0.1:5000/accepter?ip={pubip}&os={os}&country={country}&date={d1}")
Script that makes GET request to server.
I don't understand how to get the div to duplicate in such a way that the value of the old one isn't altered, and only the new one uses the value of what my flask route is returning.
I have 3 apps in django project, I created a new html file on dictionary app which is Refcode_Info.html. This page must render a simple form and linked a simple. When I click the button, form must show on screen. However when I click the button, I get 404 page and mixxed url, Likewise, I want to direct another url on this page, but seconda url already exits in this project and I have used on different stages on project but doesnt work on new html page(Refcode_Info.html). My new html may have a problems but my Accounts links is working on different stages.
This is my Refcode_Info.html codes on below.
<script>
$(document).ready(function() {
if ($(document).width() > 768) {
$("#accordion_desktop").accordion({
header: '.header',
collapsible: true,
active: false,
autoHeight: true,
heightStyle: 'content',
animate: 50
});
$("#desktop").show();
} else {
$("#accordion_mobile").accordion({
header: '.header',
collapsible: true,
active: false,
autoHeight: true,
heightStyle: 'content',
animate: 50
});
$("#mobile").show();
}
$(window).resize(function() {
if ($(document).width() > 768) {
$("#accordion_desktop").accordion({
header: '.header',
collapsible: true,
active: false,
autoHeight: true,
heightStyle: 'content',
animate: 50
});
$("#desktop").show();
$("#mobile").hide();
} else {
$("#accordion_mobile").accordion({
header: '.header',
collapsible: true,
active: false,
autoHeight: true,
heightStyle: 'content',
animate: 50
});
$("#mobile").show();
$("#desktop").hide();
}
});
});
</script>
<style>
.ui-widget-content {
border: none;
}
.ui-state-focus {
outline: none;
}
.sign-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
/* add */
justify-content: center;
/* add to align horizontal */
align-items: center;
/* add to align vertical */
}
#accordion_desktop .ui-icon {
display: none;
}
#accordion_desktop .ui-accordion-header a {
padding-left: 0;
}
#accordion_mobile .ui-icon {
display: none;
}
#accordion_mobile .ui-accordion-header a {
padding-left: 0;
}
</style>
<div id="desktop" class="container-fluid p-0" style="display:none; text-align:center;">
<div id="accordion_desktop">
<!-- Not a student-->
<div class="header m-0 p-0" style="border:none; background: #0c151D;">
<div class="row pt-5 pb-4 m-0" style="background-color: #0c151D; padding-top: 1rem !important; padding-bottom: 1rem !important;">
<div class="col-4 col-md-2 p-0">
<div class="text-right">
<img class="img-fluid" src="/static/img/studentnot.png" style="max-height: 100px;" />
</div>
</div>
<div class="col-8 col-md-10 text-center">
<p style="color:#FFFFFF; font-size:1.4em;padding-top:1.25em;">Üniversite personeli/öğrencisi değilim <img class="img-fluid" src="/static/img/plus_blue.png" style="max-height: 25px; margin-bottom: 5px; margin-left: 10px;" /></p>
</div>
</div>
</div>
<div class="row pt-4 pb-4" style="background-color:#0c151D;">
<div class="col-12 col-md-12 text-center pt-3">
<p style="color:#FFFFFF; font-size:1.2em;">Legaling'in zengin veri tabanından, şu aşamada yalnızca üniversiteler vasıtasıyla faydalanılabilmektedir. Ancak istisnai durumlarda bireysel kullanıcılara da ücretsiz erişim hakkı tanımlanabilmektedir. Bu kapsamda Legaling'i nereden duyduğunuz
ve neden tam bir erişim talep ettiğinizi bizimle paylaşırsanız başvurunuzu değerlendirmeye almaktan mutluluk duyarız.</p>
<a class="btn btn-primary" href="{% url 'Accounts:personalize' %}">Referans Kodu Ekle</a>
<a class="btn btn-primary" href="mailto:legalingnetdestek#gmail.com">Kod Talebi Gönder</a>
<a class="btn btn-primary" href="mailto:legalingnetdestek#gmail.com">Konu ile İlgili Düşünceleriniz</a>
</div>
</div>
<!-- Student -->
<div class="header m-0 p-0" style="border:none; background: #1E2329;">
<div class="row pt-5 pb-4 m-0" style="background-color:#1E2329; padding-top: 1rem !important; padding-bottom: 1rem !important;">
<div class="col-4 col-md-2 p-0">
<div class="text-right">
<img class="img-fluid" src="/static/img/student.png" style="max-height: 100px;" />
</div>
</div>
<div class="col-8 col-md-10 text-center">
<p style="color:#FFFFFF; font-size:1.4em;padding-top:1.25em;">Üniversite personeliyim/öğrencisiyim. <img class="img-fluid" src="/static/img/plus_gray.png" style="max-height: 25px; margin-bottom: 5px; margin-left: 10px;" /></p>
</div>
</div>
</div>
<div class="row pt-4 pb-4" style="background-color:#1E2329;">
<div class="col-12 col-md-12 text-center pt-3">
<p style="color:#FFFFFF; font-size:1.2em;">Legaling, belirli bir üniversiteden en az 2 personel ya da 10 öğrenciden talep gelmesi durumunda ilgili üniversite ile Legaling'in zengin veri tabanını açmak üzere temasa geçer. Bu doğrultuda Legaling'in üniversiteniz ile temasa geçmesini
istiyorsanız aşağıdaki alanları doldurunuz</p>
<a class="btn btn-primary" href="{% url 'Dictionary:getUniInfo' %}">Üniversite Bilgilerini Paylaş</a>
</div>
</div>
</div>
</div>
<!-- MOBILE -->
<div id="mobile" class="container-fluid p-0" style="display:none;">
<div id="accordion_mobile">
<!-- Not a Student -->
<div class="header m-0 p-0" style="border:none; background: #0c151D;">
<div class="row m-0 p-1" style="background-color:#0C151D; padding-top: 1rem !important; padding-bottom: 1rem !important;">
<div class="col-3 col-md-2 p-0">
<div class="sign-container text-right">
<img class="img-fluid" src="/static/img/studentnot.png" style="max-height: 60px;" />
</div>
</div>
<div class="col-8 col-md-9 text-center">
<p style="color:#FFFFFF; font-size:1.2em;">Legaling'in zengin veri tabanından, şu aşamada yalnızca üniversiteler vasıtasıyla faydalanılabilmektedir. Ancak istisnai durumlarda bireysel kullanıcılara da ücretsiz erişim hakkı tanımlanabilmektedir. Bu kapsamda Legaling'i nereden
duyduğunuz ve neden tam bir erişim talep ettiğinizi bizimle paylaşırsanız başvurunuzu değerlendirmeye almaktan mutluluk duyarız.</p>
</div>
<div class="col-1 col-md-1 p-0">
<div class="sign-container">
<img class="img-fluid" src="/static/img/plus_blue.png" style="max-height: 25px;" />
</div>
</div>
</div>
</div>
<!-- Student -->
<div class="header m-0 p-0" style="border:none; background: #1E2329;">
<div class="row p-1 m-0" style="background-color:#1E2329; padding-top: 1rem !important; padding-bottom: 1rem !important;">
<div class="col-3 col-md-2 p-0">
<div class="sign-container text-right">
<img class="img-fluid" src="/static/img/student.png" style="max-height: 60px;" />
</div>
</div>
<div class="col-8 col-md-9 text-center">
<p style="color:#FFFFFF; font-size:1.2em; padding-top: 1em;">Üniversite personeliyim/öğrencisiyim.</p>
</div>
<div class="col-1 col-md-1 p-0">
<div class="sign-container">
<img class="img-fluid" src="/static/img/plus_gray.png" style="max-height: 25px;" />
</div>
</div>
</div>
</div>
<div class="row pt-4 pb-4" style="background-color:#1E2329;">
<div class="col-12 col-md-12 text-center pt-3">
<p style="color:#FFFFFF; font-size:1.2em;">Legaling, belirli bir üniversiteden en az 2 personel ya da 10 öğrenciden talep gelmesi durumunda ilgili üniversite ile Legaling'in zengin veri tabanını açmak üzere temasa geçer. Bu doğrultuda Legaling'in üniversiteniz ile temasa geçmesini
istiyorsanız aşağıdaki alanları doldurunuz</p>
</div>
</div>
</div>
</div>
This is views.py page attached below;
def getUniInfo(request):
text = open(os.path.join(settings.BASE_DIR, "Dictionary", "templates","Refcode_Info.html"),"r",encoding="utf8")
UsageText = text.read()
text.close()
if request.method == 'POST':
form = askUniversityInfoForm(request.POST)
if form.is_valid():
obj = UserUniversity() # get new user details
obj.university = form.cleaned_data['universityName']
obj.university_user_email = form.cleaned_data['universityEmail']
obj.save()
mail_subject = "Legaling Aktivasyon Maili"
to_email = form.cleaned_data.get('email')
email = EmailMessage(mail_subject, message, to=[to_email])
email.content_subtype = "html"
email.send()
context = {'UserUniversity', UserUniversity}
return render(request, "Refcode_Info.html", context)
else:
return redirect('Dictionary:index')
else:
form = askUniversityInfoForm()
if(request.is_ajax()):
return render(request, 'usertext_partial.html', {'title':"Neden Referans Kodu Almalıyım?", 'text':UsageText})
else:
return render(request, 'usertext.html', {'title':"Neden Referans Kodu Almalıyım?", 'text':UsageText})
This is forms.py attached below;
class askUniversityInfoForm(forms.Form):
universityName= forms.CharField(label='Your University Name', max_length=100, required=True, widget=forms.TextInput())
universityEmail= forms.CharField(label='Your university Email Address', max_length=100, required=True, widget=forms.TextInput())
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.add_input(Submit('Gönder', 'Gönder', css_class='bbtn btn-block btn-success'))
super(askUniversityInfoForm, self).__init__(*args, **kwargs)
if not 'userid' in self.initial:
self.fields['name'] = forms.CharField(required=True, label="Adınız", max_length=50)
self.fields['surname'] = forms.CharField(required=True, label="Soyadınız", max_length=100)
self.fields['email'] = forms.EmailField(required=True, label="E-Posta Adresiniz", max_length=150)
self.fields['phonenumber'] = forms.RegexField(regex=r'^\([0-9]{3}\)\-?\s?[0-9]{3}\-?\s?[0-9]{2}\-?\s?[0-9]{2}$',required=False,label='Cep Telefonu Numarası', widget=forms.widgets.TextInput(attrs={'type':'tel','class':'input-phone','onfocus':'registerphoneinput();'}), error_messages = {'invalid':"Telefon Numarası Formatı Doğru Değil"})
self.fields['profession'] = ProfessionchoiceField(queryset=Profession.objects.all(), required=True,label='Mesleğiniz')
self.fields['captcha'] = ReCaptchaField(widget=ReCaptchaV2Checkbox, label='')
Also the my urls;
from django.conf.urls import url, include
from django.urls import path, re_path
from Dictionary import views
path('referencecodetext', views.referencecodetext, name='referencecodetext'),
path('getUniInfo', views.getUniInfo, name='getUniInfo'),
Also, I have url output like this, I research which is why but I couldn't found it.
enter image description here
Anyone have a idea?
I run with success a flask application interfaced with a MySQL database, all running fine.
I'm now trying to build a Dashboard page that will build charts and updates them as the data evolves.
Those charts will be filled-up with dedicated queries defined in the routes and pushed to the proper HTML template with jQuery/Ajax.
I'm stuck at the point where it seems no data gets out of my #home.route > data() function and i can't figure out why. The error in the debuger tells me that the data is "undefined" (the value data is of float type, containg "." decimals).
My .js knowledge being ridiculously low, i'd appreciate if somebody could help me progress on my error.
Thank you very much.
This is my main route.
#home.route('/admin/dashboard', methods=['GET','POST'])
def data():
conn = None
cursor = None
try:
conn = mysql.connect()
cursor = conn.cursor()
sql = "SELECT location_id, SUM(workload) FROM collaborators GROUP BY location_id ORDER BY DATE(location_id) DESC";
cursor.execute(sql)
rows = cursor.fetchall()
data = []
for row in rows:
data.append({'location_id': str(row[0]), 'workload': float(row[1])})
return jsonify({'payload': json.dumps({'workload':data,'location_id':labels})})
This is my HTML also sheltering the chart script.
<!-- app/templates/home/admin_dashboard.html -->
{% extends "base.html" %}
{% block title %}Admin Dashboard{% endblock %}
{% block body %}
<div class="intro-header">
<div class="container" style="height:50px">
<p>Dynamic chart using .JS, Ajax & jQuery</p>
</div>
<canvas id="myChart" width="100" height="70"></canvas>
<script>
$(document).ready(function(){
var _data;
var _labels;
$.ajax({
url: "/admin/dashboard",
type: "get",
dataType:"json",
data:{vals: ''},
success: function(response) {
console.log("This is the returned data: " + JSON.stringify(response));
full_data = JSON.parse(response.payload);
console.log(full_data);
_data = full_data['workload'];
_labels = full_data['location_id'];
},
error: function(error){
console.log("Here is the error res: " + JSON.stringify(error));
}
});
// define the chart data
var chartData = {
labels : _labels,
datasets : [{
label: 'workload',
fill: false,
borderColor: 'rgba(255, 25, 255, 1.0)',
data: _data,
},
]
}
// get chart canvas
var ctx = document.getElementById("myChart").getContext("2d");
// create the chart using the chart canvas
var myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
legend: { display: true },
title: {
display: false,
text: 'Predicted world population (millions) in 2050'
}
}
});
});
</script>
</div>
{% endblock %}
And finally, this is my base.HTML.
<!-- app/templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ title }} - Proc. Headcount</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/xcharts.min.css') }}"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js "></script>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="{{ url_for('static', filename='js/charts/d3.js') }}"></script>
<script src="{{ url_for('static', filename='js/charts/sugar.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/charts/xcharts.min.js') }}"></script>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top topnav" style="background-color: #0c0d29;background-color:#000000;" role="navigation">
<div class="container topnav">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<div class="logo" >
<a href="{{ url_for('home.homepage') }}">
<img src="{{STATIC_URL}}../../../static/img/Thales_Logo2.png">
</a>
</div>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
{% if current_user.is_admin %}
<li><a class="outward" href="{{ url_for('home.data') }}">Dashboard</a></li>
<li><a class="outward" href="{{ url_for('admin.list_functions') }}">Functions</a></li>
<li><a class="outward" href="{{ url_for('admin.list_roles') }}">Roles</a></li>
<li><a class="outward" href="{{ url_for('admin.list_locations') }}">Locations</a></li>
<li><a class="outward" href="{{ url_for('admin.list_collaborator') }}">Collaborators</a></li>
{% else %}
<li>Dashboard</li>
{% endif %}
<li><a class="outward" href="{{ url_for('auth.logout') }}">Logout</a></li>
<li><a><i class="fa fa-user"></i> Hi, {{ current_user.username }}!</a></li>
{% else %}
<li>Home</li>
<li>Register</li>
<li>Login</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<div class="wrapper">
{% block body %}
{% endblock %}
<div class="push"></div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-lg-12">
<ul class="list-inline">
<li>Home</li>
<li class="footer-menu-divider">⋅</li>
<li>Register</li>
<li class="footer-menu-divider">⋅</li>
<li>Login</li>
</ul>
<p class="copyright text-muted small">Thales / Procurement</p>
</div>
</div>
</div>
</footer>
</body>
</html>
for row in rows:
data.append({'location_id': str(row[0]), 'workload': float(row[1])})
I would try printing what you are returning (the jsonify) to see if that's correct, and then if it's not then I would go back to the above line and see if this is how you should be appending to an array of json objects. Will the jsonify accept that?
Okay i solved my problem I think.
Thanks to this : Accessing python list in javascript as an array
The problem was that i was not materializing the interface between my HTML template (hosting the javascript) and my Flask function executing the SQL.
I abandoned flask.jsonify / dumps method, to directly implement the value/labels names in the render_template(). I still have some improvements to do though.
Also i modified my script client-side to use {{ data|tojson|safe }}.
#home.route('/admin/dashboard', methods=['GET','POST'])
#login_required
def admin_dashboard():
# prevent non-admins from accessing the page
if not current_user.is_admin:
abort(403)
conn = None
cursor = None
try:
conn = mysql.connect()
cursor = conn.cursor()
sql = "SELECT location_id, SUM(workload) as workload FROM collaborators GROUP BY location_id;"
cursor.execute(sql)
rows = cursor.fetchall()
test = []
labels = []
for index in range(len(rows)):
test.append(rows[index][1])
labels.append(float(rows[index][0]))
return render_template('home/admin_dashboard.html', title="Dashboard", test = test, labels = labels)
except Exception as e:
print(e)
finally:
if cursor and conn:
cursor.close()
conn.close()
<script>
$(document).ready(function(){
var data = JSON.parse('{{test | tojson | safe}}');
var labels = JSON.parse('{{labels | tojson | safe}}');
console.log(labels)
$.ajax({
url: "/admin/dashboard",
type: "get",
contentType: "application/json; charset=utf-8",
dataType:"json",
data:{vals:''},
success: function(response) {
console.log(response);
full_data = JSON.parse('{{test | tojson | safe}}');
console.log(full_data);
data = full_data['data'];
labels = full_data['labels'];
},
});
// define the chart data
var chartData = {
labels: labels,
datasets : [{
label: 'workload',
fill: true,
borderColor: 'rgba(25, 25, 25, 1)',
backgroundColor:'steelblue',
data: data
}],
}
// get chart canvas
var ctx = document.getElementById("myChart").getContext("2d");
// create the chart using the chart canvas
var myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
legend: { display: true },
title: {
display: true,
text: 'Procurement Headcount'
}
}
});
});
</script>