Related
ers,
I am trying to create a vba based html web scraper to gather some data. The data I am trying to scrape is from javascript that looks similar to this:
<script src="https://d1fkb6ohkxde1z.cloudfront.net/assets/common-bundle- a24f15b690f23a668028e412a6d5243a1b0eeac497627def104363c0941da290.js"></script>
<script src="https://d1fkb6ohkxde1z.cloudfront.net/assets/private-57441f796e1722a6986c300e765cb19ea439a663b341a68647ebdb60252a0682.js"></script>
<script>
$('#onboardingModal').modal('show')
var silo = $profarmer.currentSilo;
silo.service_url = 'https://prices.profarmergrain.com.au/';
silo.clear_service_url = 'https://www.cleargrain.com.au';
silo.bhc_site_name = 'Port Adelaide Zone';
silo.bhc_site_type = 'PortZone';
silo.port_name = 'Port Adelaide';
silo.bhc_site_type = 'PortZone';
silo.bulk_handler_code = 'Zone';
silo.bulk_handler_name = 'Port Prices';
silo.grain_type = 'Wheat';
silo.grain_season = '2015';
silo.initBinGradeSelector(true, 'APW1', [{"code":"APW1","description":"Australian Premium White Wheat No 1","seasons":["2015","2016","2014"]},{"code":"H1","description":"Hard Wheat No 1","seasons":["2015","2016","2014"]},{"code":"H2","description":"Hard Wheat No 2","seasons":["2015","2016","2014"]},{"code":"HPS1","description":"Wheat - High Protein Screenings No1","seasons":["2015"]},{"code":"AUH2","description":"Australian Hard Varieties Wheat (Utility Grade)","seasons":["2015","2014"]},{"code":"APW1 FMG","description":"APW1 Floating Spread Multi-Grade","seasons":["2015","2016"]},{"code":"APW1 MG","description":"Multigrade APW1","seasons":["2015","2016","2017"]},{"code":"ASW1","description":"Australian Standard White Varieties Wheat","seasons":["2016","2015","2014"]},{"code":"AGP1","description":"Australian General Purpose No.1","seasons":["2015","2016","2014"]},{"code":"AUW1","description":"Utility Wheat","seasons":["2015","2014"]},{"code":"FED1","description":"Feed Wheat","seasons":["2015","2016"]},{"code":"SFW1","description":"Stock Feed Winter Wheat","seasons":["2015"]},{"code":"DR1","description":"Durum Wheat No.1 Grade - Protein 13.2%","seasons":["2015"]},{"code":"DR1 MG","description":"Multigrade Durum No.1","seasons":["2016"]},{"code":"DR2","description":"Durum Wheat No.2 Grade - Protein Target 12.0%","seasons":["2015"]},{"code":"DR3","description":"Durum Wheat No.3 Protein No Min","seasons":["2015"]},{"code":"SFE1","description":"Soft Wheat No.1 Grade","seasons":["2015"]}]);
silo.pricing_label = 'Port Zone Bid';
silo.port_equivalent = false;
silo.tradable = false;
silo.freight_rate = 0.0;
React.mount({
"price-chart": $profarmer.components.PriceChart,
"price-search": $profarmer.components.PriceSearch,
"merchant-prices": $profarmer.components.MerchantPrices,
"clear-grain-prices": $profarmer.components.ClearGrainPrices,
"market-commentary": $profarmer.components.MarketCommentary,
}, {
props: {
snapshot: {"bhc_site_name":"Port Adelaide Zone","port_name":"Port Adelaide","grain_type_name":"Wheat","grain_season_start_year":2015,"bulk_handler_code":"Zone","bulk_handler_name":"Port Prices","market_prices":{"APW1":{"2015":{"port_price":"266.0","price":"266.0","price_high_movement":"-4.0","prices_last_updated_at":"2016-05-31T06:10:05.000Z"},"2016":{"port_price":"255.0","price":"255.0","price_high_movement":"-6.0","prices_last_
And continues with a few hundred more prices in a similar format. Ideally I would scrap everything from the line "props:" onwards. I have a simple code to rearrange the text once in excel, but my vba code to scrape the html/java is having some troubles.
Sub ie_open()
Dim wb As Workbook
Dim ws As Worksheet
Dim TxtRng As Range
Dim ie As Object
Set ie = CreateObject("INTERNETEXPLORER.APPLICATION")
ie.NAVIGATE "https://www.profarmergrain.com.au/prices/port-adelaide-zone/Zone/wheat"
ie.Visible = True
While ie.ReadyState <> 4
DoEvents
Wend
Dim V As Variant
Set V = ie.document.getelementbyid("src") ' - need better code here
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet7")
Set TxtRng = ws.Range("A1")
TxtRng = V.innertext
End Sub
I am not sure if there is a better way to scrape an element. Instead of by id or tag, is there a way to scrape by either line number or by or by a string number?
Cheers!
I wanna use a variable as id name in selectQuery but I fail.
Hotelno is the variable of id name. How could I fix it so I could use that variable as id name ?
var hotel_1 = {
'name':"Hullett House",'url':"http://www.hulletthouse.com/",'flag':true,'photo':"../image/0.png",
'des':"Hullett House is perfectly located for both business and leisure guests in Hong Kong.",
'price':"HK$1800" };
var hotel_2 = {
'name':"Heritage Lodge",'url':"https://www.royalplaza.com.hk",'flag':false,'photo':"../image/14831652.jpg",
'des':"Heritage Lodge is located in the Western District. ",
'price':"HK$1120" };
var hotel_3 = {
'name':"Royal Plaza",'url':"https://www.royalplaza.com.hk",'flag':false,'photo':"../image/44228962.jpg",
'des':"Royal Plaza Hong Kong is located very close to shopping malls, trains and markets. ",
'price':"HK$2000" };
var hotel = [hotel_1,hotel_2,hotel_3];
function getHotel() {
var noHotel=Math.floor(Math.random()*3);
for (var i = 0; i<noHotel; i++) {
var hotelno = 'hotel'+ (i+1);
document.getElementById(hotelno).style.visibility="visible";
document.querySelector('#hotel1 .title').innerHTML=hotel[i].name; //can work
document.querySelector('#hotel1 img').src= hotel[i].photo; //can work
document.querySelector('"#"+hotelno .line').innerHTML=hotel[i].des; //can not work
}}
How I do search one string and replace it with ""?
Example:
<div id="test">
<span>test</span>
</div>
<script>
document.getElementById("test").innerHTML = ""
</script>
I want find document.getElementById("test").innerHTML = "" and replaced it with "".
Important: I'm using this code in other files of the website so just want remove this code after <div id="test">.
Thank You...
If you want to search and replace character from a string then use it.
javascript with regular expression
var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue/g, " ");
Output
Mr has a blue house and a blue car
But if you want to do it for recursive then use this:
javascript code
var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue/gi, "red");
output
Mr has a house and a car
For more details: visit
Good day;
I'm continuing my attempt to create a deck building application for Cardfight!! Vanguard
There is a rule you can't have more than 4 of the same card in a deck, and no more than 50 cards in a deck.
I'm trying to make it so that I have a counter that increases when a card is added to a deck and decreases when a card is taken out of the deck. But this counter must be for each individual card which starts off at 0 and increases by 1 every time a card with a specific name is added to the deck.
I have a vanguard object and database array where I can create new Vanguard objects easily. I have a variable within the Vanguard object (this.cardLimit = 0) which will set the card limit initially to 0 for each new card.
Then when a new card [addToDeck] is added to the deck, it will increment a counter for that specific card within the database: database[addToDeck].cardLimit++, until the maximum of 4 is reached, after which point this if statement will not work:
if (deck.length < 51 && database[addToDeck].cardLimit < 5)
My problem is - as you will see in the code below - I can't figure out a way to decrement this value when I remove a card using jquery. What I do is dynamically add card names to a div, and when a card name in that div is clicked on, it will remove not only the card from the div but the card from the deck array as well by splicing.
I can't just do database[addToDeck].cardLimit-- as you will see in my code because I use jQuery and "this" to specifically refer to the part of the div being clicked on.
My question is then.... how can I decrease the counter based on the specifications of the code I have provided so far? When my Jquery (last jQuery instance in the code) for removing the part of the deck runs, I need to decrease the counter for the specific card that was removed.
Let me know if you need any further clarification... It's not easy for me to explain my problem in simple terms. Thanks so much for reading.
JavaScript / Jquery:
function Vanguard(name,grade,skill,power,shield,critical, type, trigger, nation, clan, race, flavor, effect, imageURL){
this.name = name;
this.grade = grade;
this.skill = skill;
this.power = power;
this.shield = shield;
this.critical = critical;
this.type = type;
this.trigger = trigger;
this.nation = nation;
this.clan = clan;
this.race = race;
this.flavor = flavor;
this.effect = effect;
this.imageURL = imageURL;
this.cardLimit = 0;
};
var database = {};
database['asura kaiser'] = new Vanguard("Asura Kaiser", 3, "Twin Drive!!", 11000, "", 1, "Normal Unit", "None", "Star Gate", "Nova Grappler", "Battleroid", "The death blow! Kaiser Buster!", "<br/>[CONT](VC/RC):If you do not have another «Nova Grappler» vanguard or rear-guard, this unit gets [Power] -2000. <br/> [AUTO](VC):When this unit's drive check reveals a grade 3 «Nova Grappler», choose one of your rear-guards, and [Stand] it.", "http://images4.wikia.nocookie.net/__cb20120428001646/cardfight/images/thumb/a/a6/VGE_BT01-008EN.jpg/300px-VGE_BT01-008EN.jpg");
database['king of knights, alfred'] = new Vanguard("King of Knights, Alfred", 3, "Twin Drive!!", 10000, "", 1, "Normal Unit", "None", "United Sanctuary", "Royal Paladin", "Human", "I command you under the name of the King of Knights! Warriors, heed my call!", "<br/>[CONT](VC):Your units cannot boost this unit. <br/> [CONT](VC):During your turn, this unit gets [Power]+2000 for each of your «Royal Paladin» rear-guards. <br/> [ACT](VC/RC):[Counter Blast (3)] Search your deck for up to one grade 2 or less «Royal Paladin», call it to (RC), and shuffle your deck.", "http://images2.wikia.nocookie.net/__cb20121009013434/cardfight/images/thumb/9/95/BT01-001EN_RRR.jpg/300px-BT01-001EN_RRR.jpg");
database['dragonic overlord'] = new Vanguard("Dragonic Overlord", 3, "Twin Drive!!", 11000, "", 1, "Normal Unit", "None", "Dragon Sanctuary", "Kagerou", "Dragon", "<br/>(TD02):Reduce all to ashes, flame of the apocalypse! Eternal Flame! <br/> (BT01):Burn, flame of despair! Eternal Flame!", "<br/>[CONT](VC/RC):If you do not have another «Kagero» vanguard or rear-guard, this unit gets [Power]-2000. <br/> [ACT](VC/RC):[Counter Blast (3)] Until end of turn, this unit gets [Power]+5000, gets '[AUTO](VC/RC):When this unit's attack hits an opponent's rear-guard, [Stand] this unit', and loses 'Twin Drive!!'.", "http://images1.wikia.nocookie.net/__cb20120131161306/cardfight/images/thumb/3/33/TD02-001EN.jpg/300px-TD02-001EN.jpg");
database['ceo amaterasu'] = new Vanguard("CEO Amaterasu", 3, "Twin Drive", 10000, "", 1, "Normal Unit", "None", "United Sanctuary", "Oracle Think Tank", "Human", "<br/>(BT01):Shape my desire. Project it before me, Yata no Kagami! <br/>(EB05):Feel the flow of time. You will create the future.", "<br/>[CONT](VC):During your turn, if the number of cards in your hand is four or greater, this unit gets [Power] +4000. <br/> [AUTO](VC):At the beginning of your main phase, Soul Charge (1), look at the top card of your deck, and put that card on the top or the bottom of your deck. <br/> [AUTO](VC/RC):[Soul Blast (8) & Counter Blast (5)] When this unit's attack hits, you may pay the cost. If you do, draw up to five cards.)", "http://images2.wikia.nocookie.net/__cb20120831173054/cardfight/images/thumb/3/30/BT01-S05EN_SP.jpg/300px-BT01-S05EN_SP.jpg");
database['alfred early'] = new Vanguard("Alfred Early", 3, "Twin Drive!!", 10000, "", 1, "Normal Unit", "None", "United Sanctuary", "Royal Paladin", "Human", "To preserve the smiles of his people, the young King leads knights to battle.", "AUTO: When this unit is placed on Vanguard Circle, choose up to one card named 'Blaster Blade' from your soul, and call it to Rear-guard Circle.", "http://images1.wikia.nocookie.net/__cb20120926194218/cardfight/images/thumb/5/5e/PR-0005EN.jpg/300px-PR-0005EN.jpg");
function printVanguard(p, name){
for (var p in database[name]){
if (p !== 'imageURL'){
document.getElementById('output').innerHTML +=('<b>' + p.charAt(0).toUpperCase() + p.slice(1) + '</b>: ' + database[name][p] + '<br />');
}}
};
$(document).ready(function() {
$('#button').click(function(){
$('#output').html(""); //clear old search
$('#image').html(""); // clear old image
var userInput = $('input[name=searchItem]').val();
userInput = userInput.toLowerCase();
$('#output').append(printVanguard(userInput, userInput));
var image = $('<img>').attr('src', database[userInput].imageURL);
$('#image').append(image);
});
var deck = [];
$('#add').click(function(){
var addToDeck = $('input[name=searchItem]').val();
addToDeck = addToDeck.toLowerCase();
database[addToDeck].cardLimit++;
if (deck.length < 51 && database[addToDeck].cardLimit < 5){
deck.push(addToDeck);
$('#quantity').html("");
$('#save').prepend('<div id="quantity">' + 'Total: ' + deck.length + '</div>');
$('#save').append('<div id="cardList">' + database[deck[deck.length-1]].name + '</div>');
}
});
$(document).on('click','[id^=cardList]', function(){
$(this).remove();
deck.splice(deck[this], 1);
$('#quantity').html("");
$('#save').prepend('<div id="quantity">' + 'Total: ' + deck.length + '</div>');
});
});
HTML code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type = "text/javascript" src='script.js'>
</script>
<title></title>
</head>
<body>
<form name="searchForm">
<input type="text" id="search" placeholder="Enter Card Name" name="searchItem"/>
</form>
<div id="button">Search!</div>
<div id="add">Add to Deck</div>
<br/>
<div id="output"></div>
<div id="image"></div>
<div id="save"></div>
</body>
</html>
Fiddle: jsfiddle.net/8QR7q
Provided by Malik
Test Inputs: "Alfred Early", "CEO Amaterasu", "Dragonic Overlord", "Asura Kaiser", or "King of Knights, Alfred"
I am trying to work through how to publish items from multiple arrays while first searching through the separate array elements and then return only those items which match a certain criteria. The following code does not do this yet.
enter code here<div id="myDiv">
<script type="text/javascript">
var $ = function(id) {
return document.getElementBuId(id);
}
var title = new Array("Barbecuing in the Rain","Picnicing in the Arctic",
"How to Saute on a Radiator", "A Real Grasshopper: Bartending with Insects",
"Food with a Bullet: Cooking in Camden", "Mirepoix for Dummies");
var price = new Array(18.50, 23.95, 41.95, 5.95, 13.00, 99.00);
var binding = new Array("Hardcover", "Paperback", "Hardcover", "Paperback", "Paperback", "Hardcover");
var pubYear = new Array(2002, 1975, 2004, 2006, 2001, 1997);
var NYTBestSeller = new Array(true, true, false, false, true, true)
var seriesTitle = new Array("Food Network", "The Food Network",
"Culinary Shortcuts", "Sunset Libations",
"Food Network", "The Food Network");
var bargainBooks = ("Food Network Hot Selling Bargain Book");
for (i in title) {
if (((price[i] <= 25 && binding[i] == "Hardcover") ||
(price[i] <= 15 && binding[i] == "Softcover")) && (pubYear[i] >= 2000) &&
(NYTBestSeller[i] == true) && (seriesTitle[i] == "Food Network") || (seriesTitle[i] == "The Food Network"))
//document.write("<span color='red'>This line is red</span>");
document.write(title[i] + "<br />");
document.write(price[i] + "<br />");
document.write(binding[i] + "<br />");
document.write(pubYear[i] + "<br />");
document.write(NYTBestSeller[i] + "<br />");
document.write(seriesTitle[i] + "<br />" + "<hr/>");
}
</script>
I am searching for books that met a certain criteria and then trying to output where that book is on the page a message of Hot Selling Book in green. But I can't figure out how to make the document.write work. document.write().style.color="green" does not work.
document.write output text only, you have to write your own tags there (a div styled as green for example).
However I suggest you a different approach, what about an empty div with an id and then do the following:
document.getElementById('your-div-id').innerHTML = 'text <br /> <span style="color: green;">other text</span> and so on';
Will also reorganize code in a better way.
Document.write will only append code to the end of the output stream (the document in this case), so you can't specify where output will appear.
Edit 1:
Also, what about using objects in this case? As far as I can see, you are using arrays to emulate their behaviour:
var myObjArray = [
{
title: 'mytitle1',
price: '10$',
binding: 'dunno',
pubYear: 'dunno-again',
NYTBestSeller: true,
seriesTitle: 'Something'
},
{
...other object data...
}
]
document.getElementById('your-div-id').innerHTML += myObjArray[0].title + '<br />' + myObjArray[0].price;
Hope you can find it interesting