I am trying to scrape a row in a table with a date. I want to scrape only the third row that have the date today.
This is my mechanize code. I am trying to select the colum row witch have the date today and its and its columns:
agent.page.search("//td").map(&:text).map(&:strip)
Output:
"11-02-2011", "1", "1", "1", "1", "0", "0,00 DKK", "0,00", "0,00 DKK",
"12-02-2011", "5", "5", "1", "4", "0", "0,00 DKK", "0,00", "0,00 DKK",
"14-02-2011", "1", "3", "1", "1", "0", "0,00 DKK", ",00", "0,00 DKK",
"7", "9", "3", "6", "0", "0,00 DKK", "0,00", "0,00 DKK
"
I want to only scrape the third row that is the date today.
Rather than loop over the <td> tags using '//td', search for the <tr> tags, grab only the third one, then loop over '//td'.
Mechanize uses Nokogiri internally, so here's how to do it in Nokogiri-ese:
html = <<EOT
<table>
<tr><td>11-02-2011</td><td>1</td><td>1</td><td>1</td><td>1</td><td>0</td><td>0,00 DKK</td><td>0,00</td><td>0,00 DKK</td></tr>
<tr><td>12-02-2011</td><td>5</td><td>5</td><td>1</td><td>4</td><td>0</td><td>0,00 DKK</td><td>0,00</td><td>0,00 DKK</td></tr>
<tr><td>14-02-2011</td><td>1</td><td>3</td><td>1</td><td>1</td><td>0</td><td>0,00 DKK</td><td>,00</td><td>0,00 DKK</td></tr>
</table>
EOT
require 'nokogiri'
require 'pp'
doc = Nokogiri::HTML(html)
pp doc.search('//tr')[2].search('td').map{ |n| n.text }
>> ["14-02-2011", "1", "3", "1", "1", "0", "0,00 DKK", ",00", "0,00 DKK"]
Use the .search('//tr')[2].search('td').map{ |n| n.text } appended to Mechanize's agent.page, like so:
agent.page.search('//tr')[2].search('td').map{ |n| n.text }
It's been a while since I played with Mechanize, so it might also be agent.page.parser....
EDIT:
there will come more rows in the table. The row that i want to scrape is always the second last.
It's important to put that information into your original question. The more accurate your question, the more accurate our answers.
Related
I am trying to post a new row of data to an Excel table. I am sending a POST request to the Table / Rows. A new row is being added but with empty values. This happens both when I POST from code and also if I POST from the Microsoft Graph Explorer.
The POST statement I am using is:
POST /v1.0/drives/{driveid}/items/{itemid}/workbook/tables/{tableid}/rows
content-type: Application/Json
authorization: Bearer {access-token}
{
"value": [{
"values": [
["44444 : 22/08/2017 12:14:46",
"44444",
"22/08/2017 12:14:46",
"New Name",
"Status",
"01/10/2017 12:14:46",
"563",
"Filename"
]
],
"index": null
}]
}
I get a successful response message but with empty field values and the table has a blank row added.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives({driveid)/items(itemid)/workbook/tables({tableid})/rows/$entity",
"#odata.id": "/drives({driveid})/items({itemid})/workbook/tables({tableid})/rows(null)",
"index": 2,
"values": [
[
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
]
]
}
How do I get the POST to include the values into the new row?
After more experimenting I have found what I have done wrong. My table has more columns in it than I was posting to. You need to post to all columns. I needed to add an additional two blank fields in this case. When the correct number of values was included the post works.
The JSON needs to be formatted like this as well as needing to have a value for each column in the table.
{ "values": [ [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29" ] ] }
I have a few different channels where I am using bulk channel reports, and in the channel_basic_1a and 2a reports, I am noticing some elements that are getting returned with statistics, but no video_id to associate them with.
Has anybody else encountered this behavior? I have noticed this across several days, and it's a relatively small part of my total data set, but noticeable. This occurred three times on this one particular day, one in country US, one in ZZ and one in JO.
Here's an example json element:
{
"date": "20150731",
"card_teaser_click_rate": "0",
"subscribed_status": "subscribed",
"card_clicks": "0",
"annotation_closable_impressions": "0",
"shares": "0",
"annotation_closes": "0",
"card_impressions": "0",
"videos_removed_from_playlists": "0",
"annotation_impressions": "0",
"annotation_clickable_impressions": "0",
"annotation_click_through_rate": "0",
"views": "0",
"likes": "0",
"annotation_clicks": "0",
"comments": "0",
"average_view_duration_seconds": "0",
"live_or_on_demand": "on_demand",
"card_teaser_clicks": "0",
"videos_added_to_playlists": "0",
"card_click_rate": "0",
"dislikes": "0",
"subscribers_lost": "0",
"watch_time_minutes": "0",
"annotation_close_rate": "0",
"card_teaser_impressions": "0",
"country_code": "US",
"average_view_duration_percentage": "0",
"channel_id": "*******",
"subscribers_gained": "10",
"video_id": ""
},
I'm currently developing an app in Xcode. Within this app I want to give the user the possibility to filter the content of Table View Cells (objects) by multiple checkboxes [see picture 1].
Every object thats shown in the Table View has 8 properties which have the value 1, 2 or 3. The checkboxes shown in the filter area are in relationship with these 8 properties.
Like:
Checkbox1 = prop1
Checkbox2 = prop2
Checkbox3 = prop3
etc..
Objects arrays:
var objects:[Object] = [
Object(name: "Lorem Ipsum", prop1: "3", prop2: "1", prop3: "1", prop4: "1", prop5: "1", prop6: "1", prop7: "3", prop8: "2"),
Object(name: "Lorem Ipsum", prop1: "1", prop2: "1", prop3: "1", prop4: "3", prop5: "1", prop6: "1", prop7: "3", prop8: "2"),
Object(name: "Lorem Ipsum", prop1: "1", prop2: "2", prop3: "2", prop4: "2", prop5: "2", prop6: "1", prop7: "3", prop8: "2"),
Object(name: "Lorem Ipsum", prop1: "2", prop2: "3", prop3: "3", prop4: "1", prop5: "3", prop6: "1", prop7: "3", prop8: "2"),
Object(name: "Lorem Ipsum", prop1: "1", prop2: "3", prop3: "1", prop4: "2", prop5: "2", prop6: "3", prop7: "2", prop8: "1"),
Object(name: "Lorem Ipsum", prop1: "2", prop2: "3", prop3: "1", prop4: "1", prop5: "1", prop6: "1", prop7: "3", prop8: "2")
]
When all checkboxes are unchecked all the objects will show the same default color (blue).
But when one of the checkboxes is checked, the filter needs to change the color of the objects that have the related property to the selected checkbox, as value 2 or 3. When the value is 2 = change to green color, and when the value is 3 = change to purple color.
So for instance; if checkbox2 is selected, all objects with prop2 as 2 or 3 should have a different color [see picture 2]
I did research but couldn't find a way to do it and make it work. If somebody could help, that would be amazing!
EDIT-NOTE: If the user selects two checkboxes, for instance 1 and 2, the objects with value 3 on property 1 or 2 needs to have the color purple, even if they have a value 2 on one of these properties. So value 3 'weighs' more than 2
I would suggest maybe using a dictionary for all the checkboxes. Assign each checkbox a unique tag value (0-7).
let filters: [Int: Bool] = [0: false, 1: false ... 7:0]
When one is selected via a fund didSelect(checkbox: UIButton){ self.tableView.reloadData() }, you would update the corresponding filter by setting self.filters[checkbox.tag] = true.
Then your tableView data items should be filtered by iterating through all the filters and checking if they are true/false before assigning a color for the cell using cellForRow(at: IndexPath).
I'm trying to display a json after different SQL queries. Some of the SQL queries return one value but I got an array of results from one of the queries. You can see the example of the json that I want to show below.
{
"id": "4",
"potential": "23",
"conversion": "45",
"new": "34",
"repeat": "22",
"average": "14",
"traffic": [
{
"time": "9",
"new": "2",
"repeat": "1"
},
{
"time": "10",
"new": "6",
"repeat": "9"
}
]
}
I can display separately hash and array as json, however I can't combine them.
{
"id": "4",
"potential": "23",
"conversion": "45",
"new": "34",
"repeat": "22",
"average": "14"
}
AND
[
{
"time": 5,
"new": 0,
"repeat": 80
},
{
"time": 6,
"new": 1,
"repeat": 80
}
]
Any suggestions? Thank you
Traverse the response you get and add the data into a Hash. Here is a ruby-doc for it. If you need a bit idea of how to use hash see below code.
x = {"id" => "4", "potential" => "23","conversion"=> "45","new"=> "34","repeat"=> "22","average"=> "14"}
x["traffic"] =[{"time"=>5,"new"=>0,"repeat"=>80},{"time"=>6,"new"=>1,"repeat"=>80}]
You would have to use your logic to build the hash. I just wrote something for you. Also you can then return the hash by render :json => x.
After a lot of fixing an old app, i am now left with this
#products = {:parent_products=>[["Product title", "Product body 1", "3", "user1"], ["Product title 2", "Product body 2", "5", "user_2"]], :child_products=>[["making a reply", "user_2", "3", "4"], ["yes i read it", "user_5", "5", "6"], ["me too indeed. hurray", "user_1", "4", "7"], ["great to see this", "user_7", "3", "8"]]}
Now what I cant figure out how to do is -
Format #products[:child_products] in such a way that, if lets say #products[:child_products][2][2] includes in any of the elements in any of the elements with the inner index being [3] it should be appended to that array's last index, as the array itself.
So for example, from the above given hash we can see that
value of #products[:child_products][2][2] does have one another like it, at #products[:child_products][0][3] (which is the integer 4). Since it is being met true the new array should now look like
["making a reply","user_2", "3", "4", ["me too indeed. hurray","user_1", "4", "7"]]
Now note: the above is just an example. In other words inside the #products[:child_products] a search should made in a search a way that it looks
#products[:child_products][<any index>][2] inside #products[:child_products][<any index>][3]
Hope I am making sense so far.
Moving on, if the condition is not met or even met (as mentioned in the first point) and the arrays inside #products[:child_products] have been rearranged, it should now run another logic where
#products[:child_products][<any index>][2] should look for #product[:parent_products][<any index>][2]
And once the condition is met it should append that entire array into the array of #product[:parent_products]
So for example #product[:child_products][1][2] matches #product[:parent_products][1][2] (which is 5) then the new array set (of the respective index position) inside #product[:parent_products] should look like
["Product title 2", "Product body 2", "5", "user_2",["yes i read it", "user_5", "5", "6"]]
Thats all.
I tried my best to make sure I am stating the output clear. If you have any questions please ask.
UPDATE: I see that above is creating confusion. So here is the quick glance on what i have and what i want
What I have
#products = {:parent_products=>[["Product title", "Product body 1", "3", "user1"], ["Product title 2", "Product body 2", "5", "user_2"]], :child_products=>[["making a reply", "user_2", "3", "4"], ["yes i read it", "user_5", "5", "6"], ["me too indeed. hurray", "user_1", "4", "7"], ["great to see this", "user_7", "3", "8"]]}
And the final output I want is an array with the formatted data
[["Product title", "Product body 1", "3", "user1", ["making a reply", "user_2", "3", "4", ["me too indeed. hurray", "user_1", "4", "7"]], ["great to see this", "user_7", "3", "8"] ], ["Product title 2", "Product body 2", "5", "user_2", ["yes i read it", "user_5", "5", "6"]]]
Thanks
#products = {:parent_products=>[["Product title", "Product body 1", "3", "user_1"], ["Product title 2", "Product body 2", "5", "user_2"]],
:child_products=>[["making a reply", "user_2", "3", "4"], ["yes i read it", "user_5", "5", "6"],
["me too indeed. hurray", "user_1", "4", "7"], ["great to see this", "user_7", "3", "8"]]}
arr = #products[:parent_products].flat_map do |i|
i << #products[:child_products].select{|j| j.any? {|m| m == i[-1] || m == i[-2]}}
end
arr
# => ["Product title",
# "Product body 1",
# "3",
# "user_1",
# [["making a reply", "user_2", "3", "4"],
# ["me too indeed. hurray", "user_1", "4", "7"],
# ["great to see this", "user_7", "3", "8"]],
# "Product title 2",
# "Product body 2",
# "5",
# "user_2",
# [["making a reply", "user_2", "3", "4"],
# ["yes i read it", "user_5", "5", "6"]]]
class Product
attr_reader :description, :body, :id, :child_id
def initialize description, body, id, child_id
#description, #body, #id, #child_id = description, body, id, child_id
#children = []
end
def append child
#children << child
end
def accepts? child
child.id == self.id
end
def to_a
[description, body, id, child_id] + #children.map(&:to_a)
end
end
class ChildProduct < Product
def accepts? child
self.child_id == child.id
end
end
class ProductTransformer
def initialize products
#products = products
end
def transform
parents = #products[:parent_products].map{|e| Product.new *e}
children = #products[:child_products].map{|e| ChildProduct.new *e}
children.each do |child|
p = parents.detect{|parent| parent.accepts? child}
p.append child if p
children.each do |another|
next if another === child
child.append another if child.accepts?(another)
end
end
parents.map(&:to_a)
end
end
products = {
:parent_products=>[
["Product title", "Product body 1", "3", "user1"],
["Product title 2", "Product body 2", "5", "user_2"]],
:child_products=>[
["making a reply", "user_2", "3", "4"],
["yes i read it", "user_5", "5", "6"],
["me too indeed. hurray", "user_1", "4", "7"],
["great to see this", "user_7", "3", "8"]]
}
ProductTransformer.new(products).transform