Sending whatsapp messages via python/JS - javascript

I made a program which takes information from excel and sends messages via python.
I used selenium and "span" for finding the element I need.
now, WhatsApp changed their HTML and there is no span anymore.
the old code is here:
import time
import xlrd
from selenium import webdriver
chrome_driver_binary = "D:\pycharm\chromedriver.exe"
driver = webdriver.Chrome(chrome_driver_binary)
driver.get('http://web.whatsapp.com')
file_location = "C:\Users\ErelNahum\Desktop\data.xlsx"
book = xlrd.open_workbook(file_location)
print "there is " + str(book.nsheets) + " sheets"
sheet = book.sheet_by_index(0)
cols = sheet.ncols - 1
print "the number of cols is " + str(cols)
raw_input('Enter anything after scanning QR code')
for i in range(cols):
tel = sheet.cell_value((i+1), 0)
tel = tel.replace("\"", "")
print tel
messege = sheet.cell_value((i+1), 1)
messege = (messege +str(b+1))
user = driver.find_element_by_xpath('//span[#title = "{}"]'.format(tel))
user.click()
msg_box = driver.find_element_by_class_name('_input-container')
msg_box.send_keys(messege)
driver.find_element_by_class_name('compose-btn-send').click()
time.sleep(0.5)
if you have any idea how to change the program so it will work please show me.
I know Python, JS, C# so every language is fine.
Thank You,
Erel.

Check whatever tag surrounds the data you're trying to scrap after the span tag was removed, and adjust the code accordingly.
There is no general replacement for span. Can you provide the markup you're trying to scrap (at least the part where the span tag was)

Related

JavaScript - Why is innerHTML property displaying as text when it contains HTML?

I have the following bit of JS code being executed in a ASP.CORE View which is intended to basically set the content of an element on the page.
if (notificationBanner) {
var bannerText = unescape("#ViewData.GetClient().GetText("$.resetCredentials.step2.otpSendBanner")");
console.log(bannerText);
notificationBanner.innerHTML = bannerText;
}
The following is being logged in browser console:
<p>A One Time Password (OTP) has been sent to your mobile number below. Enter the OTP in the field below. <strong>The OTP is valid for 10 minutes</strong>.</p>
And the element ends up like this:
However this is not correct, I want the part in <strong></strong> to be bold. Why is it adding it as text?
I was looking for a vanilla JS solution so looking at the post crayon provided. Found a good solution. Thanks for your help.
function decodeHtml(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
if (notificationBanner) {
var bannerText = unescape("#ViewData.GetClient().GetText("$.resetCredentials.step2.otpSendBanner")");
console.log(bannerText);
notificationBanner.innerHTML = decodeHtml(bannerText);
}

Add attachment by url to Outlook mail

The context
There is a button on the homepage of each document set in a document library on a SharePoint Online environment. When the button is clicked, an Outlook window opens with the title and body set and all the files in the document set should be added as the attachments.
The code
Here's the code I have so far:
var olApp = new ActiveXObject("Outlook.Application");
var olNs = olApp.GetNameSpace("MAPI");
var olItem = olApp.CreateItem(0);
var signature = olItem.HTMLBody;
signature.Importance = 2;
olItem.To = "";
olItem.Cc = "";
olItem.Bcc = "";
olItem.Subject = "Pre filled title";
olItem.HTMLBody =
"<span style='font-size:11pt;'>" +
"<p>Pre filled body</p>" +
"</span>";
olItem.HTMLBody += signature;
olItem.Display();
olItem.GetInspector.WindowState = 2;
var docUrl = "https://path_to_site/Dossiers/13245_kort titel/New Microsoft Word Document.docx";
olItem.Attachments.Add(docUrl);
The Problem
When I run this code, an Outlook window opens with everything set correctly. But on the line where the attachment is added I get following very vague error message:
SCRIPT8: The operation failed.
I thought it could be the spaces in the url so I replaced them:
docUrl = docUrl.replace(/ /g, "%20");
Also didn't work (same error) and providing all parameters like this also didn't work:
olItem.Attachments.Add(docUrl, 1, 1, "NewDocument");
Passing a path to a local file (e.g. C:/folder/file.txt) or a publicly available url to an image does work. So my guess is it has something to do with permissions or security. Does anybody know how to solve this?
PS: I know using an ActiveX control is not the ideal way of working (browser limitations, security considerations, ...) but the situation is what it is and not in my power to change.
You cannot pass a url to MailItem.Attachments.Add in OOM (it does work in Redemption - I am its author - for RDOMail.Attachments.Add). Outlook Object Model only allows a fully qualified path to a local file or a pointer to another item (such as MailItem).

extract data from javascript using Python

I am a new user to Python, and I have inherited a Python notebook from my predecessor that I want to improve. The purpose of it is to grab product details from a website.
How it works:
It scrapes the script from a website using beautiful soup:
source = urllib2.urlopen('http://www.testwebsite.html').read()
soup = bs4.BeautifulSoup(source)
job_postings = soup.findAll("script")
job_postings = [jp for jp in job_postings if not jp.get('type') is None
and ''.join(jp.get('type')) =="text/javascript"
and ''.join(jp.get('type')) =="text/javascript"]
it returns all the script in the webpage:
(1st part of data)
window.wf=window.wf||{};wf.appData=wf.appData||{};wf.appData.product_data_TEST123=wf.appData.product_data_TEST123||{};wf.appData.product_data_TEST123 = {"sku":"TES123","is_grid_view":false,,"default_img_display":0,"manufacturer_name":"Supplier1","product_name":"product test","part_number":"1234","list_price":1000,"is_price_hidden":false,"base_price":1000,"has_opt":true,"opt_details":[{"option_ids":[],"regular_price":2681.25],"has_free_shipping":false,,"total_qty":1,"display_set_quantity":1,"is_standard_layout":true,"page_type":"ProductPage"};Y_config.app.product_data_TEST123 = {"sku":"TEST123",........ same info here ....};
2 sd part of data:
\n wf.extend({"YUI_config":{"app":{"pageAlias":"ProductPage"}},"wf":{"appData":{"pageAlias":"ProductPage",,"mkcName":"AU: FurnitureRoom","productReviews":{"b_show_review_tags":false,"kit_subgroup_price":null,"catalog_currency":"AUD","price_model":null,"colors":"",,"available_after":{"date":"2016-07-28 18:05:16.000000","timezone":"Australia\\/Sydney"},"inventory_info":{"sku":"TEST123",,"latest_inventory_update":"2016-07-29 00:45:06","option_ids":[],"available_quantity":17,"display_quantity":17,","quantity_available_string":" more then 10 in Stock","short_lead_time_id":2,"short_lead_time_string":"Leaves warehouse in 1 to 3 business days"}}};
Then I extract the data I need:
jsonfile = re.findall(r'wf.appData.product_data_[A-Z]{4}[0-9]{4} = (\{.*});YUI_config.app.product_data_',str(job_postings))
I have this:
{"sku":"TEST123","is_grid_view":false,,"default_img_display":0,"manufacturer_name":"Supplier1","product_name":"product test","part_number":"1234","list_price":1000,"is_price_hidden":false,"base_price":1000,"has_opt":true,"opt_details":[{"option_ids":[],"regular_price":2681.25],"has_free_shipping":false,,"total_qty":1,"display_set_quantity":1,"is_standard_layout":true,"page_type":"ProductPage"}
My problem is now: I want to add the "inventory_info" list to my data
I've tried:
jsonfile = re.findall(r'inventory_info' = (\{.*}),str(job_postings))
or
Jsonfile = re.compile('inventory_info' = ({.*?});', re.DOTALL)
Neither of those work.
I'm knowledge of Python is very limited so I'm a bit lost now.
Thanks for your help.
You may have already found the answer to your question but here it goes anyways.
For getting inventory_info, you could always do a split (assuming job_postings is converted to type string), as so:
inventory_info = job_postings.split("inventory_info:")[1].split("}")[0] + "}"
job_postings += inventory_info

What's the best method to EXTRACT product names given a list of SKU numbers from a website?

I have a problem.
I have a list of SKU numbers (hundreds) that I'm trying to match with the title of the product that it belongs to. I have thought of a few ways to accomplish this, but I feel like I'm missing something... I'm hoping someone here has a quick and efficient idea to help me get this done.
The products come from Aidan Gray.
Attempt #1 (Batch Program Method) - FAIL:
After searching for a SKU in Aidan Gray, the website returns a URL that looks like below:
http://www.aidangrayhome.com/catalogsearch/result/?q=SKUNUMBER
... with "SKUNUMBER" obviously being a SKU.
The first result of the webpage is almost always the product.
To click the first result (through the address bar) the following can be entered (if Javascript is enabled through the address bar):
javascript:{document.getElementsByClassName("product-image")[0].click;}
I wanted to create a .bat file through Command Prompt and execute the following command:
firefox http://www.aidangrayhome.com/catalogsearch/result/?q=SKUNUMBER javascript:{document.getElementsByClassName("product-image")[0].click;}
... but Firefox doesn't seem to allow these two commands to execute in the same tab.
If that worked, I was going to go to http://tools.buzzstream.com/meta-tag-extractor, paste the resulting links to get the titles of the pages, and export the data to CSV format, and copy over the data I wanted.
Unfortunately, I am unable to open both the webpage and the Javascript in the same tab through a batch program.
Attempt #2 (I'm Feeling Lucky Method):
I was going to use Google's &btnI URL suffix to automatically redirect to the first result.
http://www.google.com/search?btnI&q=site:aidangrayhome.com+SKUNUMBER
After opening all the links in tabs, I was going to use a Firefox add-on called "Send Tab URLs" to copy the names of the tabs (which contain the product names) to the clipboard.
The problem is that most of the results were simply not lucky enough...
If anybody has an idea or tip to get this accomplished, I'd be very grateful.
I recommend using JScript for this. It's easy to include as hybrid code in a batch script, its structure and syntax is familiar to anyone comfortable with JavaScript, and you can use it to fetch web pages via XMLHTTPRequest (a.k.a. Ajax by the less-informed) and build a DOM object from the .responseText using an htmlfile COM object.
Anyway, challenge: accepted. Save this with a .bat extension. It'll look for a text file containing SKUs, one per line, and fetch and scrape the search page for each, writing info from the first anchor element with a .className of "product-image" to a CSV file.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
set "skufile=sku.txt"
set "outfile=output.csv"
set "URL=http://www.aidangrayhome.com/catalogsearch/result/?q="
rem // invoke JScript portion
cscript /nologo /e:jscript "%~f0" "%skufile%" "%outfile%" "%URL%"
echo Done.
rem // end main runtime
goto :EOF
#end // end batch / begin JScript chimera
var fso = WSH.CreateObject('scripting.filesystemobject'),
skufile = fso.OpenTextFile(WSH.Arguments(0), 1),
skus = skufile.ReadAll().split(/\r?\n/),
outfile = fso.CreateTextFile(WSH.Arguments(1), true),
URL = WSH.Arguments(2);
skufile.Close();
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
// returns a DOM root object
function fetch(url) {
var XHR = WSH.CreateObject("Microsoft.XMLHTTP"),
DOM = WSH.CreateObject('htmlfile');
WSH.StdErr.Write('fetching ' + url);
XHR.open("GET",url,true);
XHR.setRequestHeader('User-Agent','XMLHTTP/1.0');
XHR.send('');
while (XHR.readyState!=4) {WSH.Sleep(25)};
DOM.write(XHR.responseText);
return DOM;
}
function out(what) {
WSH.StdErr.Write(new Array(79).join(String.fromCharCode(8)));
WSH.Echo(what);
outfile.WriteLine(what);
}
WSH.Echo('Writing to ' + WSH.Arguments(1) + '...')
out('sku,product,URL');
for (var i=0; i<skus.length; i++) {
if (!skus[i]) continue;
var DOM = fetch(URL + skus[i]),
anchors = DOM.getElementsByTagName('a');
for (var j=0; j<anchors.length; j++) {
if (/\bproduct-image\b/i.test(anchors[j].className)) {
out(skus[i]+',"' + anchors[j].title.trim() + '","' + anchors[j].href + '"');
break;
}
}
}
outfile.Close();
Too bad the htmlfile COM object doesn't support getElementsByClassName. :/ But this seems to work well enough in my testing.

Problem formating Html string in Javascript to send mail

I am trying to send an email (using Outlook mail) from a jsp page.
Requirement is, when the user clicks on send email button the data stored in a string
(with HTML tags) should be passed to the mailbody.
But the problem is, the text displayed in mail body is not formatted as HTML text.
Could you please suggest how to format it as HTML text in Outlook Doc.
I have used the below code in a function-
function OpenOutlookDoc(whatform,msgBody)
{
outlookApp = new ActiveXObject("Outlook.Application");
nameSpace = outlookApp.getNameSpace("MAPI");
mailFolder = nameSpace.getDefaultFolder(6);
mailItem = mailFolder.Items.add(whatform);
mailItem.Display(0);
mailItem.To = "abc#xyz.com";
mailItem.Subject = "TEST MAIL";
mailItem.Messageclass = whatform;
mailItem.Body = msgBody; //the text here is concatenated with HTML tags
mailItem.Send();
}
Thanks for you upcoming help..
After some google'ing:
The MSDN should help:
http://msdn.microsoft.com/en-us/library/aa171418%28v=office.11%29.aspx
The article includes an example to send html emails using vb-script. Converting that to javascript should not be hard - but since activex only works from within Internet Explorer you might as well use vbscript.
Try adding message.IsBodyHtml = true; to your code.
otherwise u can refer this example.

Categories

Resources