I'm writing an API that accesses bible passages from http://labs.bible.org/, and the JSON responses come back without a "response" header, or any hierarchy names. Firebug is showing that my GET requests come back as 200 status, but the response tab is always empty. If I type the url directly into the browser I get the results I want, but I don't know how to handle the JSON like that. Example: http://labs.bible.org/api/?passage=luke+9&formatting=full&type=json.
This is what the JSON looks like.
[
{
"bookname": "Luke",
"chapter": "9",
"verse": "1",
"text": "<t /><p class=\"bodytext\">After<n id=\"1\" /> Jesus<n id=\"2\" /> called<n id=\"3\" /> the twelve<n id=\"4\" /> together, he gave them power and authority over all demons and to cure<n id=\"5\" /> diseases,",
"title": "The Sending of the Twelve Apostles"
},
{
"bookname": "Luke",
"chapter": "9",
"verse": "2",
"text": "and he sent<n id=\"1\" /> them out to proclaim<n id=\"2\" /> the kingdom of God<n id=\"3\" /> and to heal the sick.<n id=\"4\" />"
},
{
"bookname": "Luke",
"chapter": "9",
"verse": "3",
"text": "He<n id=\"1\" /> said to them, “Take nothing for your<n id=\"2\" /> journey – no staff,<n id=\"3\" /> no bag,<n id=\"4\" /> no bread, no money, and do not take an extra tunic.<n id=\"5\" />"
},
{
"bookname": "Luke",
"chapter": "9",
"verse": "4",
"text": "Whatever<n id=\"1\" /> house you enter, stay there<n id=\"2\" /> until you leave the area.<n id=\"3\" />"
},
{
"bookname": "Luke",
"chapter": "9",
"verse": "5",
"text": "Wherever<n id=\"1\" /> they do not receive you,<n id=\"2\" /> as you leave that town,<n id=\"3\" /> shake the dust off<n id=\"4\" /> your feet as a testimony against them.”"
},
{
"bookname": "Luke",
"chapter": "9",
"verse": "6",
"text": "Then<n id=\"1\" /> they departed and went throughout<n id=\"2\" /> the villages, proclaiming the good news<n id=\"3\" /> and healing people everywhere.</p>"
},
{
"bookname": "Luke",
"chapter": "9",
"verse": "7",
"text": "<t /><p class=\"bodytext\">Now Herod<n id=\"1\" /> the tetrarch<n id=\"2\" /> heard about everything that was happening, and he was thoroughly perplexed,<n id=\"3\" /> because some people were saying that John<n id=\"4\" /> had been raised from the dead,",
"title": "Herod’s Confusion about Jesus"
},
(...)
]
So how do I write the code to access and parse the JSON, and how would I cycle through all the results?
These are my functions for getting and parsing the JSON:
function callApi(argument, callBack){
var requestUrl = apiUrl+argument+type;
try{
var request = new XMLHttpRequest();
request.addEventListener("readystatechange",
function() {callBack(request);}, false);
request.open("GET", requestUrl, true);
request.setRequestHeader("Accept", "application/json; charset=utf-8");
request.send();
}//end try
catch(exception){
alert("Request Failed");
}//end catch
}//end function callApi
function parseData(request){
if(request.readyState==4 && request.status==200){
var data = JSON.parse(request.responseText);
displayNames(data);
}//end if
}// end function parseData
What if you were to try using a different JSON URL like this: http://labs.bible.org/api/?passage=luke+9:3&type=json&callback=? (removing &formatting=full and adding &callback=? at the end.)
If you get the response without the formatting tags (all of the <HTML> tags) it seems to parse for me, at least in this example on jsFiddle:
http://jsfiddle.net/L8Fed/2/
Update: Here is an example of how jQuery could be used here to grab the JSON from your URL:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
var json_url = "http://labs.bible.org/api/?passage=luke+9:3&type=json&callback=?";
$.getJSON(json_url, function(json_response) {
for(var i = 0; i < json_response.length; i++) {
alert(json_response[i].text);
}
});
});
</script>
Basically, this code:
Includes jQuery
Puts the JavaScript into the ready function (more details here...)
Makes sure to call the API URL that includes the &callback=? at the end (for this reason)
Calls jQuery's $.getJSON() function (that uses your API URL and gets the response back named json_response)
Loops through the json_response and allows you to get whatever values you need. (And you'll probably want to take out the alert() function at some point... ;)
Related
I need to extract structured data for recipes from a website using JSOUP (or any other effective method) using Coldfusion.
The data is structure as follows: https://developers.google.com/search/docs/advanced/structured-data/recipe
I need to get the JSON from the page and parse it into useable variables.
I have tried a number of different options without success. I do not know JSOUP and will appreciate your help.
The data looks like this:
<script type="application/ld+json">
{
"#context": "https://schema.org/",
"#type": "Recipe",
"name": "Party Coffee Cake",
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"author": {
"#type": "Person",
"name": "Mary Stone"
},
"datePublished": "2018-03-10",
"description": "This coffee cake is awesome and perfect for parties.",
"prepTime": "PT20M",
"cookTime": "PT30M",
"totalTime": "PT50M",
"keywords": "cake for a party, coffee",
"recipeYield": "10",
"recipeCategory": "Dessert",
"recipeCuisine": "American",
"nutrition": {
"#type": "NutritionInformation",
"calories": "270 calories"
},
"recipeIngredient": [
"2 cups of flour",
"3/4 cup white sugar",
"2 teaspoons baking powder",
"1/2 teaspoon salt",
"1/2 cup butter",
"2 eggs",
"3/4 cup milk"
],
"recipeInstructions": [
{
"#type": "HowToStep",
"name": "Preheat",
"text": "Preheat the oven to 350 degrees F. Grease and flour a 9x9 inch pan.",
"url": "https://example.com/party-coffee-cake#step1",
"image": "https://example.com/photos/party-coffee-cake/step1.jpg"
},
{
"#type": "HowToStep",
"name": "Mix dry ingredients",
"text": "In a large bowl, combine flour, sugar, baking powder, and salt.",
"url": "https://example.com/party-coffee-cake#step2",
"image": "https://example.com/photos/party-coffee-cake/step2.jpg"
},
{
"#type": "HowToStep",
"name": "Add wet ingredients",
"text": "Mix in the butter, eggs, and milk.",
"url": "https://example.com/party-coffee-cake#step3",
"image": "https://example.com/photos/party-coffee-cake/step3.jpg"
},
{
"#type": "HowToStep",
"name": "Spread into pan",
"text": "Spread into the prepared pan.",
"url": "https://example.com/party-coffee-cake#step4",
"image": "https://example.com/photos/party-coffee-cake/step4.jpg"
},
{
"#type": "HowToStep",
"name": "Bake",
"text": "Bake for 30 to 35 minutes, or until firm.",
"url": "https://example.com/party-coffee-cake#step5",
"image": "https://example.com/photos/party-coffee-cake/step5.jpg"
},
{
"#type": "HowToStep",
"name": "Enjoy",
"text": "Allow to cool and enjoy.",
"url": "https://example.com/party-coffee-cake#step6",
"image": "https://example.com/photos/party-coffee-cake/step6.jpg"
}
],
"aggregateRating": {
"#type": "AggregateRating",
"ratingValue": "5",
"ratingCount": "18"
},
"video": {
"#type": "VideoObject",
"name": "How to make a Party Coffee Cake",
"description": "This is how you make a Party Coffee Cake.",
"thumbnailUrl": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"contentUrl": "http://www.example.com/video123.mp4",
"embedUrl": "http://www.example.com/videoplayer?video=123",
"uploadDate": "2018-02-05T08:00:00+08:00",
"duration": "PT1M33S",
"interactionStatistic": {
"#type": "InteractionCounter",
"interactionType": { "#type": "WatchAction" },
"userInteractionCount": 2347
},
"expires": "2019-02-05T08:00:00+08:00"
}
}
</script>
I have tried the following:
<cfset source = "https://www.allrecipes.com/recipe/216319/homemade-sweet-italian-sausage-mild-or-hot/">
<cfhttp method="get" url="#source#" result="theresult" useragent="Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.7 (KHTML, like Gecko) Chrome/5.0.391.0 Safari/533.7">
<cfhttpparam type="header" name="Accept-Encoding" value="gzip,deflate,sdch" >
<cfhttpparam type="header" name="Proxy-Connection" value="keep-alive" >
<cfhttpparam type="header" name="Accept" value="application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5">
<cfhttpparam type="header" name="Accept-Language" value="en-US,en;q=0.8">
<cfhttpparam type="header" name="Accept-Charset" value="ISO-8859-1,utf-8;q=0.7,*;q=0.3">
<cfhttpparam type="cookie" name="some-cookie" value="1">
</cfhttp>
With he above I get the web page.
I then try to extract the JSON:
<cfscript>
// Create the jsoup object
Jsoup = createObject("java", "org.jsoup.Jsoup");
// HTML string
html = "#theresult.filecontent#";
// Parse the string
document = Jsoup.parse(html);
// Extract content
title = document.title();
tags = document.select("script[type=application/ld+json]");
</cfscript>
<cfdump var="#tags#">
<cfloop index="e" array="#tags#">
<cfoutput>
#e.attr("content")#<br>
</cfoutput>
</cfloop>
But I get nothing returned.
<script type="application/ld+json">[
{
"#context": "http://schema.org",
"#type": "BreadcrumbList",
...
}
</script>
The <script> tag doesn't have an attribute named "content" (only one named "type"). To retrieve the tag contents (or its inner html) use the Element.html() method. Then deserialize the returned contents as json:
<cfscript>
Jsoup = createObject("java", "org.jsoup.Jsoup");
document = Jsoup.parse( theResult.fileContent );
tag = document.select("script[type=application/ld+json]").first();
if (isJSON(tag.html())) {
contents = deserializeJSON( tag.html() );
writeDump(contents);
}
</cfscript>
I am creating a normal HTTPS web-service to interact with Alexa. I am able to receive the request in the service and when i am returning response in the same structure as Alexa is expecting! i am getting an error. I am unable to get what's the problem.. the JSON body and Headers are set as per the standards. I am not using lambda, but trying to interact with Alexa with a normal HTTPS service.
Header:
HTTP/1.1 200 ok
content-type = application/json;charset=UTF-8
//Response JSON which is not been identified by alexa
{
"version": "1.0",
"sessionAttribute": {},
"response": {
"outputSpeech": {
"ssml": "<speak> Donut and Coffeee Aussie Style</speak>",
"type": "SSML"
},
"card": {
"content": "to the world",
"title": "Ava"
},
"speechletResponse": {
"outputSpeech": {
"ssml": "<speak>Donut and Coffee Aussie Style</speak>"
},
"card": {
"content": "to the world",
"title": "Ava"
},
"shouldEndSession": "true"
}
}
}
I found what was the problem with my response codes. The fields sessionAttributes speechletResponse are optional fields. The actual field which was missing in above JSON response is the type key value in card response. Even thought the card object itself is optional. If you are using it then you have to have a field called as type in the same. working json response below. Hope this helps the people who are trying to invade the alexa space.
{
"version": "1.0",
"sessionAttribute": {},
"response": {
"outputSpeech": {
"ssml": "<speak> Donut and Coffeee Aussie Style</speak>",
"type": "SSML"
},
"card": {
"type":"Standard",
"content": "to the world",
"title": "Ava"
},
"speechletResponse": {
"outputSpeech": {
"ssml": "<speak>Donut and Coffee Aussie Style</speak>"
},
"card": {
"content": "to the world",
"title": "Ava"
},
"shouldEndSession": "true"
}
}
}
I'm looking to return multiple responses to a user. For instance this might be an image and a text block, or a text block and a list.
So far I've not been able to find a way of doing this, everything I try either results in one of the payloads not displaying or it failing completely.
Here's an example of an attempt at displaying a text block and a list:
{
speech:"myMessage",
displayText:"myMessage",
data:{
facebook:{
"attachment": {
"type": "template",
"payload": {
"template_type": "list",
"top_element_style": "compact",
"elements": [
{
"title": "£10",
"image_url": "http://example.com/example.jpg",
"subtitle": "An amazing t-shirt"
},
{
"title": "£30",
"image_url": "http://example.com/example.jpg",
"subtitle": "Another amazing t-shirt"
},
{
"title": "£40",
"image_url": "http://example.com/example.jpg",
"subtitle": "An amazing t-shirt"
}
]
}
}
}
},
contextOut:[],
source:"webhook"
}
Any ideas on where I'm going wrong?
Each message is separate, but you can send a batch request to the graph API to dispatch all the messages with a single API call:
https://developers.facebook.com/docs/graph-api/making-multiple-requests/
I'm trying to make a custom YQL table to access a user's likes through the Tumblr API. I made the following table in the YQL editor and saved it as tumblr.likes:
<?xml version="1.0" encoding="UTF-8"?>
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd">
<meta>
<author>nonphoto</author>
<documentationURL>http://www.tumblr.com/docs/api</documentationURL>
<sampleQuery>select * from {table} where username='XXX' api_key='XXX'</sampleQuery>
</meta>
<bindings>
<select itemPath="response.liked_posts" produces="JSON">
<urls>
<url>http://api.tumblr.com/v2/blog/{username}.tumblr.com/likes</url>
</urls>
<inputs>
<key id="username" type="xs:string" paramType="path" required="true" />
<key id="api_key" type="xs:string" paramType="query" required="true" />
</inputs>
</select>
</bindings>
</table>
If this is correct then I should be able to type this query into the YQL console and get a JSON response back from Tumblr:
use "XXX" as tumblr.likes;
select * from tumblr.likes where username='XXX' and api_key='XXX';
But null appears in the results entry of the response, even if debug and diagnostics are checked to prevent caching. The response even shows the correct URL, which works if I just copy and paste it into my browser. Am I missing something? Here's an example response:
{
"query": {
"count": 0,
"created": "2016-01-15T21:44:36Z",
"lang": "en-US",
"diagnostics": {
"url": [
{
"execution-start-time": "2",
"execution-stop-time": "8",
"execution-time": "6",
"id": "579e13ad-a7c3-4eea-81d9-41fda5caf243",
"content": "http://sherpa-bcp5903.dht.yahoo.com:4080/YDHTWebService/V1/get/yql.global/store%3A%2F%2FoSSGByQMlFLQhMqNCwUcp1"
},
{
"execution-start-time": "14",
"execution-stop-time": "1137",
"execution-time": "1123",
"id": "ffab25db-521f-4795-9220-a82e2ac33a9d",
"content": "http://api.tumblr.com/v2/blog/XXX.tumblr.com/likes?api_key=XXX"
}
],
"publiclyCallable": "true",
"user-time": "1146",
"service-time": "1129",
"build-version": "0.2.942"
},
"results": null
}
}
i am new to JSON. Here i am facing problem how to get file location from JSON object, i am using javascript to parse the json
{
"_embedded": {
"binaries": [
{
"fileLocation": "http://images.clipartpanda.com/sports-equipment-clipart-black-and-white-soccer-ball-hi.png",
"username": "testuser3",
"description": "The company required the 28-year-old's help on a matter the directors felt could affect the share price: its Wikipedia page. Short, uninteresting .",
"createdAt": "2015-02-01T21:47:07.000+0000",
"updatedAt": "2015-02-01T22:42:16.000+0000"
},
{
"fileLocation": "http://images.clipartpanda.com/sports-equipment-clipart-black-and-white-soccer-ball-hi.png",
"username": "Sumanth",
"description": "Sample",
"createdAt": "2015-02-23T21:37:13.000+0000",
"updatedAt": "2015-02-23T21:43:11.000+0000"
},
{
"fileLocation": "http://images.clipartpanda.com/sports-equipment-clipart-black-and-white-soccer-ball-hi.png",
"username": "as",
"description": "as",
"createdAt": "2015-02-02T22:46:00.000+0000",
"updatedAt": "2015-02-27T22:06:18.000+0000"
}
]
}
}
i want to read all file locations from JSON object .
Can anyone help me. Thanks in advance
The way you are trying to access fileLocation looks right:
data._embedded.binaries[1].fileLocation
Before that, to parse your data use:
parsed = JSON.parse(data);
Here's a fiddle: http://jsfiddle.net/01aL5upc/
Note that I did remove whitespace and the apostrophe in 28-year-old's in the fiddle, to put it in to a string rather than an ajax request.