I am new to Powershell, and I suck at html.
There's a page with a table, and each cell has a ahref link, the value of the link is dynamic, but the link which I want to automate-clicking is always in the first cell.
I know there's cellindex in html/JS, is it usable in PS?
For example, let's say I have this table on a website.
<table>
<tr>
<td>
<a href="http://example1.com">
<div style="height:100%;width:100%">
hello world1
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="http://example2.com">
<div style="height:100%;width:100%">
hello world2
</div>
</a>
</td>
</tr>
<tr>
<td>
<a href="http://example3.com">
<div style="height:100%;width:100%">
hello world3
</div>
</a>
</td>
</tr>
</table>
And I want to make powershell to always click on the first link, the link inside is dynamic though.
Any ideas? Hints?
The result of Invoke-WebRequest returns a property named Links that is a collection of all the hyperlinks on a web page.
For example:
$Web = Invoke-webrequest -Uri 'http://wragg.io' $Web.Links | Select innertext,href
Returns:
innerText href
--------- ----
Mark Wragg http://wragg.io
Twitter https://twitter.com/markwragg
Github https://github.com/markwragg
LinkedIn https://uk.linkedin.com/in/mwragg
If the link you want to capture is always the first in this list you could get it by doing:
$Web.Links[0].href
If it's the second [1], third [2] etc. etc.
I don't think there is an equivalent of "cellindex", although there is a property named AllElements that you can access via an array index. E.g if you wanted the second element on the page you could for example do:
$Web.AllElements[2]
If you need to get to a specific table in the page and then access links inside of that table you'd probably need to iterate through the AllElements property until you reached the table you wanted. For example if you know the links were in the third table on the page:
$Links = #()
$TableCount = 0
$Web.AllElements | ForEach-Object {
If ($_.tagname -eq 'table'){ $TableCount++ }
If ($TableCount -eq 3){
If ($_.tagname -eq 'a') {
$Links += $_
}
}
}
$Links | Select -First 1
Ok, the Invoke-webrequest method is working with mark's link but with my page; but I noticed a pattern that may can be used:
I noticed the the following:
<table id="row" class="simple">
<thead>
<tr>
<th></th>
<th class="centerjustify">File Name</th>
<th class="centerjustify">File ID</th>
<th class="datetime">Creation Date</th>
<th class="datetime">Upload Date</th>
<th class="centerjustify">Processing Status</th>
<th class="centerjustify">Exceptions</th>
<th class="centerjustify">Unprocessed Count</th>
<th class="centerjustify">Discarded Count</th>
<th class="centerjustify">Rejected Count</th>
<th class="centerjustify">Void Count</th>
<th class="centerjustify">PO Total Count</th>
<th class="centerjustify">PO Total Amount</th>
<th class="centerjustify">CM Total Count</th>
<th class="centerjustify">CM Total Amount</th>
<th class="centerjustify">PO Processed Count</th>
<th class="centerjustify">PO Processed Amount</th>
<th class="centerjustify">CM Processed Count</th>
<th class="centerjustify">CM Processed Amount</th>
<th class="centerjustify">Counts At Upload</th></tr></thead>
<tbody>
<tr class="odd">
<td><input type="radio" disabled="disabled" name="checkedValue" value="12047" /></td>
<td class="leftjustify textColorBlack">
520170123000000_520170123000000_20170327_01.txt</td>
<td class="centerjustify textColorBlack">1</td>
<td class="datetime textColorBlack">Mar 27, 2017 0:00</td>
<td class="datetime textColorBlack">Mar 27, 2017 10:33:24 PM +03:00</td>
<td class="centerjustify textColorBlack">
The fId part in "loadConfirmationDetails.htm?fId=12047" is dynamic; and it's the last part of the next page;
For example: "https://aaa.xxxxxxx.com/aaa/community/loadConfirmationDetails.htm?fId=12047
And table's ID is unique, called "row" - I wonder if I can use a completely another way; other than invoking the webpage, by auto-copying this id info from its source html and concatenate it with the main link?
I am really out of ideas beyond that.
Related
I'm working on optimizing a website for visually impaired. I have a table on the page in the following format -
<table>
<thead>
<tr>
<th>Number</th>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
...
</tbody>
</table>
Currently the screen reader is announcing "row 1 col 1 number" but the expectation is that it should announce "row 1 col 1 number column header" when its a element. How can I configure it? Setting role="columnheader" is not working.
It is scope you are looking for to associate columns and rows.
scope="col" will associate a table header as a column header.
You can also associate a row header if you wish with scope="row"
<table>
<caption>My table caption - don't forget this so people know what a table is for / about</caption>
<thead>
<tr>
<th scope="col">Number</th>
<th scope="col">Name</th>
<th scope="col">Surname</th>
</tr>
</thead>
<tbody>
<tr>
<td scope="row">1</td>
<td>John</td>
<td>Smith</td>
</tr>
<tr>
<td scope="row">2</td>
<td>Mike</td>
<td>Simmons</td>
</tr>
</tbody>
</table>
See https://www.w3.org/TR/WCAG20-TECHS/H63.html for more info on this technique.
p.s. don't forget to add a <caption> to your table!
So, my problem is so basic but i cant solve it.
I'm trying to create dynamic table header with *ngFor.
<table>
<tr>
<th>Entry Warehouse</th>
<th colspan="2" *ngFor="let data of datas">
SomeText
</th>
</tr>
<tr>
<th>More Text</th>
<div *ngFor="let data of datas">
<th>A little text again</th>
<th>A little text again</th>
</div>
</tr>
</table>
Anyway, this solution suicide themself at that point. If datas length more than 1, div tag is underscoring th tag in same cell.
If i try another solution like this;
<table>
<tr>
<th>Entry Warehouse</th>
<th colspan="2" *ngFor="let data of datas">
SomeText
</th>
</tr>
<tr>
<th>More Text</th>
<th *ngFor="let data of datas">A little text again</th>
<th *ngFor="let data of datas">A little text again</th>
</tr>
</table>
it looks like works but actually not. Because at this time the next th tag doesnt start before the previous loop ends.
In angular 2+ you can use<ng-container> tags
<ng-conatiner *ngFor="let i of items">
<th>i</th>
</ng-conatiner>
I'm trying to print the detail on a check in NetSuite using the HTML portion of the Advanced PDF functionality.
I'm printing a table using HTML, where the top row is the header, and the remaining rows are the data i'd like to display. The check contains multiple bills, and I would like to display the details of these multiple bills.
The code I'm using is below. I print the header row, and then attempt to print the details rows.
The issue I'm facing: I can print 1 row just fine, but when I try to print multiple rows, NetSuite crashes and gives me the following error message: "An unexpected error has occurred. Please click here to notify support and provide your contact information."
<#if check.apply?has_content><#list check.apply as apply>
<table style="position: absolute;overflow: hidden;left: 36pt;top: 15pt;width: 436pt;border-collapse: collapse;border: 2px solid black;">
<thead>
<tr>
<th bgcolor="#000000"><font color="white">Date</font></th>
<th bgcolor="#000000"><font color="white">Description</font></th>
<th bgcolor="#000000"><font color="white">Orig. Amt.</font></th>
<th bgcolor="#000000"><font color="white">Amt. Due</font></th>
<th bgcolor="#000000"><font color="white">Discount</font></th>
<th bgcolor="#000000"><font color="white">Amount</font></th>
</tr>
</thead>
<tbody>
<tr>
<td>${apply.applydate}</td>
<td>${apply.refnum}</td>
<td>${apply.total}</td>
<td>${apply.due}</td>
<td>${apply.disc}</td>
<td>${apply.amount}</td>
</tr>
</tbody>
</#list></table>
</#if>
I think this "<#list check.apply as apply>" should be placed after "</thead>" since you only want the table header to be created once. Something like this
<#if check.apply?has_content>
<table style="position: absolute;overflow: hidden;left: 36pt;top: 15pt;width: 436pt;border-collapse: collapse;border: 2px solid black;">
<thead>
<tr>
<th bgcolor="#000000"><font color="white">Date</font></th>
<th bgcolor="#000000"><font color="white">Description</font></th>
<th bgcolor="#000000"><font color="white">Orig. Amt.</font></th>
<th bgcolor="#000000"><font color="white">Amt. Due</font></th>
<th bgcolor="#000000"><font color="white">Discount</font></th>
<th bgcolor="#000000"><font color="white">Amount</font></th>
</tr>
</thead>
<tbody>
<#list check.apply as apply>
<tr>
<td>${apply.applydate}</td>
<td>${apply.refnum}</td>
<td>${apply.total}</td>
<td>${apply.due}</td>
<td>${apply.disc}</td>
<td>${apply.amount}</td>
</tr>
</#list>
</tbody>
</table>
</#if>
How do I get all the links in a table based on the table caption?
<table class="wikitable sortable plainrowheaders">
<caption>Film</caption>
<tr>
<th scope="col">Year</th>
<th scope="col">Title</th>
<th scope="col">Role</th>
<th scope="col" class="unsortable">Notes</th>
</tr>
<tr>
<td style="text-align:center;">1997</td>
<th scope="row"><i><span class="sortkey">Ice Storm, The</span><span class="vcard"><span class="fn">The Ice Storm</span> </span></i></th>
<td>Libbets Casey</td>
<td>First professional role</td>
</tr>
</table>
I tried this
doc = Nokogiri::HTML(str)
doc.xpath('//table[caption=''Film'']//a/#href').each do |href|
p href
end
But this doesn't print anything.
You can write your code as below :-
require 'nokogiri'
doc = Nokogiri::HTML::Document.parse <<-EOT
<table class="wikitable sortable plainrowheaders">
<caption>Film</caption>
<tr>
<th scope="col">Year</th>
<th scope="col">Title</th>
<th scope="col">Role</th>
<th scope="col" class="unsortable">Notes</th>
</tr>
<tr>
<td style="text-align:center;">1997</td>
<th scope="row"><i><span class="sortkey">Ice Storm, The</span><span class="vcard"><span class="fn">The Ice Storm</span> </span></i></th>
<td>Libbets Casey</td>
<td>First professional role</td>
</tr>
</table>
EOT
doc.xpath("//table[./caption[text()='Film']]//a").each do |node|
p node['href']
end
# >> "/wiki/The_Ice_Storm_(film)"
Something I've recently discovered is that I can set a table cell to have multiple axises using a combination of the headers property on the td and the axis property on any related th. Example:
<table>
<caption>Country Toy Codes</caption>
<thead>
<tr>
<th scope="col row"></th>
<th scope="col" id="us" axis="country">US</th>
<th scope="col" id="ca" axis="country">CA</th>
<th scope="col" id="uk" axis="country">UK</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" id="robots" axis="toys">Robots</th>
<td headers="us robots">ABC</td>
<td headers="ca robots">DEF</td>
<td headers="uk robots">GHI</td>
</tr>
<tr>
<th scope="row" id="dolls" axis="toys">Dolls</th>
<td headers="us dolls">JKL</td>
<td headers="ca dolls">MNO</td>
<td headers="uk dolls">PQR</td>
</tr>
<tr>
<th scope="row" id="slinkys" axis="toys">Slinkys</th>
<td headers="us slinkys">STU</td>
<td headers="ca slinkys">VWX</td>
<td headers="uk slinkys">YZ1</td>
</tr>
<tr>
<th scope="row" id="legos" axis="toys">Legos</th>
<td headers="us legos">AB1</td>
<td headers="ca legos">CD1</td>
<td headers="uk legos">EF1</td>
</tr>
</tbody>
</table>
This has clear benefits for non-visual browsers, but I was thinking it could also be useful for javascript and css. The only problem is that I'm not seeing a way to directly access the axis type of the header id of the cell, either after selecting or for selection purpose.
Ideally, I would like to do either of the following (rough pseduo-code ahead):
Selector:
td['axis=toys'] // Would select all td's with a header id that resolves to a header having axis value "toys"
Getter:
$('td').axisValue("toys") // would return the value, if applicable, of header id of header value with axis value of toys.
For the getter, I could loop through each header each time and find the element from the id in the DOM and then the axis value, but if there is a way to do this more directly, I'm sure it's also more optimized by the browser.
For the selector, the closest I can think of (in js) is to take the given axis value, find all ids using that axis value and then comma-separate each option to grab them all, such as
[headers~=us], [headers~=ca], [headers~=uk]
Does anyone know if header id's axis name is available either via a method or directly on the td element?