So I'm about to create a project which basically makes an API call, then take data, look for photos and display for user as a slideshow.
I want to make an API call to National Geographic Photo Of The Day, and I have found National Geographic Photo Of The Day Archive
and I want to make a call to that website, save somewhere all photos from that gallery and then let user decide if he likes photos or not. How can I approach my goal? For now I have only tried to establish connection with linked gallery
package javaapplication1;
import java.net.*;
import java.io.*;
import javax.imageio.ImageIO;
public class JavaApplication1 {
public static void main(String[] args) throws Exception {
URL natgeo = new URL("https://www.nationalgeographic.com/photography/photo-of-the-day/archive/");
URLConnection yc = natgeo.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
and read in console output, but have no idea how to approach reading what came back as answer. I don't know if national geographic api exists, so don't know which approach would be better - finding API and make call for those photos or parse page and look for images and save them locally.
Appreciate all help!
What you're trying to do is called "Web Scraping". You don't just have to make a connection with the gallery, you also have to parse the HTML and pull out the URL for the image, then download the image. I suggest you look into jsoup, a Java library built for this stuff. For image downloading a manipulation, the Java Image IO library has a lot of great functionality.
Related
I want to set up the REST API to support file downloads via Java (The java part is not needed at the moment -- I am saying it in here so you can make your answer more specific for my problem).
How would I do that?
For example, I have this file in a folder (./java.jar), how can I stream it in such a way for it to be downloadable by a Java client?
I forgot to say that this, is for some paid-content.
My app should be able to do this
Client: Post to server with username,pass.
Rest: Respond accordingly to what user has bought (so if it has bought that file, download it)
Client: Download file and put it in x folder.
I thought of encoding a file in base64 and then posting the encoded result into the usual .json (maybe with a nice name -- useful for the java application, and with the code inside -- though I would not know how I should rebuild the file at this point). <- Is this plausible? Or is there an easier way?
Also, please do not downvote if unnecessary, although there is no code in the question, that doesn't mean I haven't researched it, it just means that I found nothing suitable for my situation.
Thanks.
What you need is a regular file streaming, using a valid URL.
Below code is an excerpt from here
import java.net.*;
import java.io.*;
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("http://www.oracle.com/");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
For your needs, based on your updated comments on the above answer, you could call your REST endpoint after user logs in(with Auth and other headers/body you wish to receive) and proceed to the download.
Convert your jar/downloadable content to bytes. More on this
Java Convert File to Byte Array and visa versa
Later, in case if you dont want regular streaming as aforementioned in previous answers, you can put the byte content in the body as Base64 String. You can encode to Base64 from your byte array using something like below.
Base64.encodeToString(byte[], Base64.NO_WRAP + Base64.URL_SAFE);
Reference from here: How to send byte[] and strings to a restful webservice and retrieve this information in the web method implementation
Again, there are many ways to do this, this is one of the ways you can probably do using REST.
Final update (please see comments)
I have given up on implementing my own QR generator due to GAE limitations. The former Google Charts API services still can be used, and also replicated using ZXing's servlet. For more details, see this link. Thank you for the answers.
Update 2 (see original question below)
So I dug into the source of ZXing and they seem to use BufferedImage in all of their processes. My question now could be phrased as:
Is there any way to use ZXing with Google App Engine?
Is there any way to generate a QR code in a servlet that could be
deployed to Google App Engine?
Update (see original question below)
The following line causes the error apparently:
MatrixToImageWriter.writeToStream(encoded, "png", outs);
It seems to be using BufferedImage. Is it possible to convert a BitMatrix to a byte[] without doing this step?
Original question
I am trying to create a servlet on Google App Engine to return a QR code with given parameters. So far I have created solutions both with QRGen and ZXing which work perfectly when testing in App Engine local development mode. My problem is that both of these implementations fail after I deploy my servlet to App Engine, saying either
Could not initialize class
com.google.apphosting.runtime.security.shared.stub.java.awt.image.BufferedImage
or
java.awt.Image is a restricted class. Please see the Google App Engine
developer's guide for more details.
I don't understand completely how these tools work internally, what I know that java.awt.image classes are not on the Class whitelist. My question is that is there any way to get around this security feature, and actually return a QR code from a servlet. Here is my latest implementation (which works fine in development mode, but also fails on a deployed servlet) using ZXing (it seems to offer more options than QRGen):
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
String returnString = "myString";
Writer writer = new QRCodeWriter();
BitMatrix encoded = null;
try
{
encoded = writer.encode(returnString, BarcodeFormat.QR_CODE, 300, 300);
}
catch (WriterException ex)
{
Logger.getLogger(QRService.class.getName()).log(Level.SEVERE, null, ex);
}
ByteArrayOutputStream outs = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(encoded, "png", outs);
byte[] out = outs.toByteArray();
Blob qrImage = new Blob(out);
resp.setContentType("image/jpeg");
resp.getOutputStream().write(qrImage.getBytes());
}
Here, look into the Google Charts API
https://developers.google.com/chart/infographics/docs/qr_codes
It seems it allows you to create a QR code with simple HTTP GET request. To create an HTTP GET request in App Engine, try this:
https://developers.google.com/appengine/docs/java/urlfetch/
I am working with Dropbox API using JAVA SDK. I try to get the thumbnail for each image in my dropbox account via API. Honestly, after I read the class and they just provided the description which is not useful enough for the beginner. I begin my code like this
public void getThumbnails() throws DropboxException{
DropboxInputStream dis = api.getThumbnailStream("/Koala.jpg", ThumbSize.ICON_256x256, ThumbFormat.JPEG);
}
What I don't understand is:
I should return something to client side in order to show the thumbnail I got from DropboxAPI but I don't know what I should return. Maybe DropboxInputStream?
How do I get the thumbnail from API? I try to find the example or guide for a day but I can't find any guide...
please someone guide me how to get the thumbnail via dropbox API
DropboxInputStream is just a FilterInputStream so after you get the input stream like you wrote you can just iterate the input stream and read it.
Then it's only a question of the way you need to present it.
Is it a Swing application you are writing? how do you need to show that image?
You should be able to read the Image with ImageIO.read
Image image = ImageIO.read(dis);
http://docs.oracle.com/javase/6/docs/api/javax/imageio/ImageIO.html
I know how to read the HTML code of a website, for example, the next java code reads all the HTML code from http://www.transfermarkt.co.uk/en/fc-barcelona/startseite/verein_131.html this is a website that shows all the football players of F.C. Barcelona.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class ReadWebPage {
public static void main(String[] args) throws IOException {
String urltext = "http://www.transfermarkt.co.uk/en/fc-barcelona/startseite/verein_131.html";
URL url = new URL(urltext);
BufferedReader in = new BufferedReader(new InputStreamReader(url
.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
// Process each line.
System.out.println(inputLine);
}
in.close();
}
}
OK, but now I need to work with the HTML code, I need to obtain the names ("Valdés, Victor", "Pinto, José Manuel", etc...) and the positions (Goalkeeper, Defence, Midfield, Striker) of each of the players of the team. For example, I need to create an ArrayList <String> PlayerNames and an ArrayList <String> PlayerPositions and put on these arrays all the names and positions of all the players.
How I can do it??? I can't find the code example that can do it on google..... code examples are welcome
thanks
I would recommend using HtmlUnit, which will give you access to the DOM tree of the HTML page, and even execute JavaScript in case the data are dynamically put in the page using AJAX.
You could also use JSoup: no JavaScript, but more lightweight and support for CSS selectors.
I think that the best approach is first to purify HTML code into the valid XHTML form, and them apply XSL transformation - for retrieving some part of information you can use XPATH expressions. The best available html tag balancer is in my opinion neko HTML (http://nekohtml.sourceforge.net/).
You might like to take a look at htmlparser
I used this for something similar.
Usage something like this:
Parser fullWebpage = new Parser("WEBADDRESS");
NodeList nl = fullWebpage.extractAllNodesThatMatch(new TagNameFilter("<insert html tag>"));
NodeList tds = nodes.extractAllNodesThatMatch(new TagNameFilter("a"),true);
String data = tds.toHtml();
Java has its own, built-in HTML parser. A positive feature of this parser it that it is error tolerant and would assume some tags even if they are missing or misspelled. While called swing.text.html.Parser, it has actually nothing shared with Swing (and with text only as much as HTML is a text). Use ParserDelegator. You need to write a callback for use with this parser, otherwise it is not complex to use. The code example (written as a ParserDelegator test) can be found here. Some say it is a reminder of the HotJava browser. The only problem with it, seems not upgraded to the most recent versions of HTML.
The simple code example would be
Reader reader; // read HTML from somewhere
HTMLEditorKit.ParserCallback callback = new MyCallBack(); // Implement that interface.
ParserDelegator delegator = new ParserDelegator();
delegator.parse(reader, callback, false);
I've found a link that is just what you was looking for:
http://tiny-url.org/work_with_html_java
As an example suppose i want my program to
Vist stackoverflow everyday
Find the most question in some tag for that day
Format it and then send it to my email address
I don't know how to do it , i know php more , but i have some understnading of Java , j2ee , spring MVC but not java network programming
Any guidelines how should i go
I'd start by looking at the Stack Exchange API.
What you can possibly do is extract the contents of url and write it to a string buffer and then using JSOUP.jar (used to parse html elements) parse the html string to get the content of your choice.I have a small sample which does exactly that i read all the contents of the url into a string and then parse the content based on the CLASS TAG (here in this case it is question-hyperlink)
package com.tps.examples;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class URLGetcontent {
public static void main(String args[]) {
try {
URL url = new URL("http://stackoverflow.com/questions");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
StringBuffer str = new StringBuffer();
while ((line = rd.readLine()) != null) {
// System.out.println(line);
str.append(line);
}
Document doc = Jsoup.parse(str.toString());
Elements content = doc.getElementsByClass("question-hyperlink");
for (int i = 0; i < content.size(); i++) {
System.out.println("Question: " + (i + 1) + ". " + content.eq(i).text());
System.out.println("");
}
System.out.println("*********************************");
} catch (Exception e) {
}
}
}
Once the data is extracted you can use javamail class to send the content in email.
As you're wanting to retrieve data from a website (i.e. over HTTP), you probably want to look into using one of many HTTP clients already written in Java or PHP.
Apache HTTP Client is a good Java client used by many people. If you're invoking a RESTful interface, Jersey has a nice client library.
On the PHP side of things, someone already mentioned file_get_contents... but you could also look into the cURL library
As far as emailing goes, there's a JavaMail API (I'll admit I'm not familiar with it), or depending on your email server you might jump through other hoops (for example Exchange can send email through their SOAP interfaces.)
with file_get_contents() in PHP you cal also fetch files via HTTP:
$stackoverflow = file_get_contents("http://stackoverflow.com");
Then you have to parse this. For many sites there are special APIs which you can request via JSON or XML.
If you know shell scripting (that's the way i do it for many sites - works great with a cronjob :)) then you can use sed, wget, w3m, grep, mail to do it...
StackOverflow and other stackexchange sites provide a simple API (stackapps). You Please check out.